diff --git a/arch/arm/arm64/tls.c b/arch/arm/arm64/tls.c index d4e9307282..653b8b20aa 100644 --- a/arch/arm/arm64/tls.c +++ b/arch/arm/arm64/tls.c @@ -42,19 +42,17 @@ #endif /* CONFIG_LIBCONTEXT_CLEAR_TBSS */ #include -#include -#include -#include -#include + #include #include +#include +#include +#include #if CONFIG_LIBUKDEBUG #include -#include #else /* !CONFIG_LIBUKDEBUG */ #define UK_ASSERT(..) do {} while (0) -#define uk_pr_debug(..) do {} while (0) #endif /* !CONFIG_LIBUKDEBUG */ /* @@ -284,6 +282,6 @@ void ukarch_tls_area_init(void *tls_area) UK_ASSERT(ukarch_tls_area_size() == (__sz) (writepos - (__u8 *) tls_area)); - uk_hexdumpCd(tls_area, ukarch_tls_area_size()); + uk_hexdumpCk(UK_PRINT_KLVL_DEBUG, tls_area, ukarch_tls_area_size()); } diff --git a/arch/x86/ectx.c b/arch/x86/ectx.c index 16894bc761..5d1c5924dc 100644 --- a/arch/x86/ectx.c +++ b/arch/x86/ectx.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include #include /* memset_isr */ enum x86_save_method { @@ -215,12 +215,12 @@ void ukarch_ectx_assert_equal(struct ukarch_ectx *state) if (memcmp_isr(current, state, ectx_size) != 0) { uk_pr_crit("Modified ECTX detected!\n"); uk_pr_crit("Current:\n"); - uk_hexdumpk(KLVL_CRIT, current, ectx_size, + uk_hexdumpk(UK_PRINT_KLVL_CRIT, current, ectx_size, UK_HXDF_ADDR | UK_HXDF_GRPQWORD | UK_HXDF_COMPRESS, 2); uk_pr_crit("Expected:\n"); - uk_hexdumpk(KLVL_CRIT, state, ectx_size, + uk_hexdumpk(UK_PRINT_KLVL_CRIT, state, ectx_size, UK_HXDF_ADDR | UK_HXDF_GRPQWORD | UK_HXDF_COMPRESS, 2); diff --git a/arch/x86/x86_64/tls.c b/arch/x86/x86_64/tls.c index 21cae5a9ef..eb57723ffe 100644 --- a/arch/x86/x86_64/tls.c +++ b/arch/x86/x86_64/tls.c @@ -40,7 +40,7 @@ #include #include -#include +#include #include #include #include @@ -201,5 +201,5 @@ void ukarch_tls_area_init(void *tls_area) ukarch_tls_tcb_init((void *) ukarch_tls_tlsp(tls_area)); #endif /* CONFIG_UKARCH_TLS_HAVE_TCB */ - uk_hexdumpCd(tls_area, ukarch_tls_area_size()); + uk_hexdumpCk(UK_PRINT_KLVL_DEBUG, tls_area, ukarch_tls_area_size()); } diff --git a/lib/Makefile.uk b/lib/Makefile.uk index d297030fb4..09dc820bdd 100644 --- a/lib/Makefile.uk +++ b/lib/Makefile.uk @@ -55,6 +55,7 @@ $(eval $(call import_lib,$(CONFIG_UK_BASE)/lib/ukmmap)) $(eval $(call import_lib,$(CONFIG_UK_BASE)/lib/ukmpi)) $(eval $(call import_lib,$(CONFIG_UK_BASE)/lib/uknetdev)) $(eval $(call import_lib,$(CONFIG_UK_BASE)/lib/uknofault)) +$(eval $(call import_lib,$(CONFIG_UK_BASE)/lib/ukprint)) $(eval $(call import_lib,$(CONFIG_UK_BASE)/lib/ukring)) $(eval $(call import_lib,$(CONFIG_UK_BASE)/lib/uksched)) $(eval $(call import_lib,$(CONFIG_UK_BASE)/lib/ukschedcoop)) diff --git a/lib/nolibc/syslog.c b/lib/nolibc/syslog.c index 40b2e7f93a..9eda61dd03 100644 --- a/lib/nolibc/syslog.c +++ b/lib/nolibc/syslog.c @@ -39,16 +39,14 @@ static int log_facility = LOG_USER; static const int level_map[] = { - KLVL_CRIT, /* LOG_EMERG */ - KLVL_CRIT, /* LOG_ALERT */ - KLVL_CRIT, /* LOG_CRIT */ - KLVL_ERR, /* LOG_ERR */ - KLVL_WARN, /* LOG_WARNING */ - KLVL_INFO, /* LOG_NOTICE */ - KLVL_INFO, /* LOG_INFO */ - - /* This one maps to a different macro on unikraft */ - /* KLVL_INFO, */ /* LOG_DEBUG */ + UK_PRINT_KLVL_CRIT, /* LOG_EMERG */ + UK_PRINT_KLVL_CRIT, /* LOG_ALERT */ + UK_PRINT_KLVL_CRIT, /* LOG_CRIT */ + UK_PRINT_KLVL_ERR, /* LOG_ERR */ + UK_PRINT_KLVL_WARN, /* LOG_WARNING */ + UK_PRINT_KLVL_INFO, /* LOG_NOTICE */ + UK_PRINT_KLVL_INFO, /* LOG_INFO */ + UK_PRINT_KLVL_DEBUG, /* LOG_DEBUG */ }; static const char *facility_to_str(int facility) @@ -127,14 +125,9 @@ void vsyslog(int priority, const char *format, va_list ap) priority &= LOG_PRIMASK; /* Forward call */ - if (priority == LOG_DEBUG) { - uk_printd("[%s] ", facility_to_str(facility)); - uk_printd(format, ap); - } else { - priority = MAX(priority, 0); - priority = MIN(priority, (int)ARRAY_SIZE(level_map)); - uk_printk(level_map[priority], "[%s] ", - facility_to_str(facility)); - uk_printk(level_map[priority], format, ap); - } + priority = MAX(priority, 0); + priority = MIN(priority, (int)ARRAY_SIZE(level_map)); + uk_printk(level_map[priority], "[%s] ", + facility_to_str(facility)); + uk_printk(level_map[priority], format, ap); } diff --git a/lib/posix-mmap/tests/test_posix_mmap.c b/lib/posix-mmap/tests/test_posix_mmap.c index 12057c4b1e..2ccf1251e5 100644 --- a/lib/posix-mmap/tests/test_posix_mmap.c +++ b/lib/posix-mmap/tests/test_posix_mmap.c @@ -15,7 +15,7 @@ #include #define pr_info(fmt, ...) \ - _uk_printk(KLVL_INFO, __NULL, __NULL, 0x0, fmt, ##__VA_ARGS__) + _uk_printk(UK_PRINT_KLVL_INFO, __NULL, __NULL, 0x0, fmt, ##__VA_ARGS__) #define pm_bug_on(cond) \ do { \ diff --git a/lib/syscall_shim/Config.uk b/lib/syscall_shim/Config.uk index c1811142e2..9760171af3 100644 --- a/lib/syscall_shim/Config.uk +++ b/lib/syscall_shim/Config.uk @@ -66,7 +66,6 @@ if LIBSYSCALL_SHIM depends on LIBSYSCALL_SHIM_HANDLER bool "'strace'-like messages for binary system calls" default n - select LIBUKDEBUG if !LIBUKCONSOLE help Emits a `strace`-like message as soon as a binary system call request was finished handling. The result/return code of the system call is diff --git a/lib/syscall_shim/include/uk/syscall.h b/lib/syscall_shim/include/uk/syscall.h index 2171e49f4a..80bf90a5c8 100644 --- a/lib/syscall_shim/include/uk/syscall.h +++ b/lib/syscall_shim/include/uk/syscall.h @@ -204,7 +204,7 @@ typedef long uk_syscall_arg_t; #define UK_EXECENV_DECLMAPx(__syscall_rarg, nr_args, ...) \ __syscall_rarg UK_ARG_EMAPx(nr_args, __VA_ARGS__) -#if CONFIG_LIBSYSCALL_SHIM_DEBUG_SYSCALLS || CONFIG_LIBUKDEBUG_PRINTD +#if CONFIG_LIBSYSCALL_SHIM_DEBUG_SYSCALLS #define UK_ARG_FMT_MAP0(...) #define UK_ARG_FMT_MAP2(m, type, arg) m(type, arg) #define UK_ARG_FMT_MAP4(m, type, arg, ...) m(type, arg) ", " UK_ARG_FMT_MAP2(m, __VA_ARGS__) @@ -219,15 +219,18 @@ typedef long uk_syscall_arg_t; #define UK_S_ARG_FMT_LONGX(type, arg) "(" STRINGIFY(type) ") 0x%lx" #define __UK_SYSCALL_PRINTD(x, rtype, fname, ...) \ - _uk_printd(uk_libid_self(), __STR_BASENAME__, __LINE__, \ + _uk_printk(UK_PRINT_KLVL_DEBUG | UK_PRINT_RAW, \ + uk_libid_self(), __STR_BASENAME__, __LINE__, \ "(" STRINGIFY(rtype) ") " STRINGIFY(fname) \ "(" UK_ARG_FMT_MAPx(x, UK_S_ARG_FMT_LONGX, __VA_ARGS__) ")\n" \ UK_ARG_EMAPx(x, UK_S_ARG_CAST_LONG, __VA_ARGS__) ) -#define __UK_SYSCALL_EXECENV_PRINTD(x, rtype, fname, ...) \ - uk_printd("\nInvoking context saving %s system call.\n", \ +#define __UK_SYSCALL_EXECENV_PRINTD(x, rtype, fname, ...) \ + uk_printk(UK_PRINT_KLVL_DEBUG | UK_PRINT_RAW, \ + "\nInvoking context saving %s system call.\n", \ STRINGIFY(fname)); \ - _uk_printd(uk_libid_self(), __STR_BASENAME__, __LINE__, \ + _uk_printk(UK_PRINT_KLVL_DEBUG | UK_PRINT_RAW, \ + uk_libid_self(), __STR_BASENAME__, __LINE__, \ "(" STRINGIFY(rtype) ") " STRINGIFY(fname) \ "( execenv 0x%lx, " UK_ARG_FMT_MAPx(x, \ UK_S_ARG_FMT_LONGX,\ diff --git a/lib/syscall_shim/uk_syscall_binary.c b/lib/syscall_shim/uk_syscall_binary.c index 557be308b1..54c24032c0 100644 --- a/lib/syscall_shim/uk_syscall_binary.c +++ b/lib/syscall_shim/uk_syscall_binary.c @@ -42,11 +42,7 @@ #include #include #if CONFIG_LIBSYSCALL_SHIM_STRACE -#if CONFIG_LIBUKCONSOLE -#include -#else /* !CONFIG_LIBUKCONSOLE */ #include -#endif /* !CONFIG_LIBUKCONSOLE */ #endif /* CONFIG_LIBSYSCALL_SHIM_STRACE */ /** @@ -107,8 +103,9 @@ void ukplat_syscall_handler(struct uk_syscall_ctx *usc) #endif /* CONFIG_LIBSYSCALL_SHIM_HANDLER_ULTLS */ #if CONFIG_LIBSYSCALL_SHIM_DEBUG_HANDLER - _uk_printd(uk_libid_self(), __STR_BASENAME__, __LINE__, - "Binary system call request \"%s\" (%lu) at ip:%p (arg0=0x%lx, arg1=0x%lx, ...)\n", + _uk_printk(UK_PRINT_KLVL_DEBUG, + uk_libid_self(), __STR_BASENAME__, __LINE__, + "Binary system call request \"%s\" (%lu) at ip:%p (arg0=0x%lx, arg1=0x%lx, ...)\n", uk_syscall_name(execenv->regs.__syscall_rsyscall), execenv->regs.__syscall_rsyscall, (void *)execenv->regs.__syscall_rip, @@ -133,18 +130,7 @@ void ukplat_syscall_handler(struct uk_syscall_ctx *usc) execenv->regs.__syscall_rarg3, execenv->regs.__syscall_rarg4, execenv->regs.__syscall_rarg5); - /* - * FIXME: - * Replace the call to `uk_pr_info` with a call to the kernel printing - * library once that exists. We also don't want to print all the meta - * data that `uk_pr_info` includes. Note also that right now, debug - * print calls also turn into a no-op if `ukconsole` is not available. - */ -#if CONFIG_LIBUKCONSOLE - uk_console_out(prsyscallbuf, (__sz) prsyscalllen); -#else /* !CONFIG_LIBUKCONSOLE */ - uk_pr_info(prsyscallbuf); -#endif /* !CONFIG_LIBUKCONSOLE */ + uk_printk(UK_PRINT_KLVL_INFO | UK_PRINT_RAW, "%s", prsyscallbuf); #endif /* CONFIG_LIBSYSCALL_SHIM_STRACE */ #if CONFIG_LIBSYSCALL_SHIM_HANDLER_ULTLS diff --git a/lib/ukdebug/Config.uk b/lib/ukdebug/Config.uk index e88673aa18..3c3d452d4d 100644 --- a/lib/ukdebug/Config.uk +++ b/lib/ukdebug/Config.uk @@ -5,99 +5,6 @@ menuconfig LIBUKDEBUG default y if LIBUKDEBUG -config LIBUKDEBUG_PRINTK - bool "Enable kernel messages (uk_printk)" - default y - help - Enables kernel message console. - -choice - prompt "Kernel message level" - default LIBUKDEBUG_PRINTK_ERR - depends on LIBUKDEBUG_PRINTK - help - Set the level of detail of kernel messages - -config LIBUKDEBUG_PRINTK_INFO - bool "Show all types of messages" - -config LIBUKDEBUG_PRINTK_WARN - bool "Show critical, error, and warning messages" - -config LIBUKDEBUG_PRINTK_ERR - bool "Show critical and error messages (default)" - -config LIBUKDEBUG_PRINTK_CRIT - bool "Show critical messages only" -endchoice - -config LIBUKDEBUG_PRINTD - bool "Enable debug messages globally (uk_printd)" - default n - help - Enables debug messages globally. Without this configuration, - debug messages can still be enabled for each compilation unit - individually. This happens as soon the UK_DEBUG macro is defined. - -choice - prompt "Message redirection" - default LIBUKDEBUG_REDIR_PRINTD - help - Output for uk_printk() and uk_printd() - -config LIBUKDEBUG_NOREDIR - bool "No redirection" - help - Keep debug and kernel output separated - -config LIBUKDEBUG_REDIR_PRINTD - bool "Debug messages on kernel output (default)" - help - Debug message are redirected to standard kernel output - -config LIBUKDEBUG_REDIR_PRINTK - bool "Kernel messages on debug output" - depends on LIBUKDEBUG_PRINTK - help - Kernel message are redirected to the standard debug output -endchoice - -config LIBUKDEBUG_PRINT_TIME - bool "Show timestamp in messages" - default y - -config LIBUKDEBUG_PRINT_THREAD - bool "Show thread identifier" - default n - depends on LIBUKSCHED - help - Prints the thread name or, if unnamed, the address of - the TCB (struct uk_thread) of the currently scheduled - thread. For the case `uk_thread_current()` returns - NULL, the placeholder "<>" is printed instead. - -config LIBUKDEBUG_PRINT_CALLER - bool "Show caller information" - default n - help - Prints the current return address and current stack frame - address for the message command. The return address can be - useful in combination with a debugger. The stack frame - address is a handy information for analysing the state of - the currently active stack. - Format: "{r:,f:}" - -config LIBUKDEBUG_PRINT_SRCNAME - bool "Print source code location of messages" - default y - -config LIBUKDEBUG_ANSI_COLOR - bool "Colored output" - default n - help - Use ANSI control sequences to colorize console output. - Before activating this option, please make sure that - your console output/display supports ANSI. config LIBUKDEBUG_ENABLE_ASSERT bool "Enable assertions" diff --git a/lib/ukdebug/Makefile.uk b/lib/ukdebug/Makefile.uk index 929388aca4..e3b7840402 100644 --- a/lib/ukdebug/Makefile.uk +++ b/lib/ukdebug/Makefile.uk @@ -7,15 +7,6 @@ CXXINCLUDES-$(CONFIG_LIBUKDEBUG) += -I$(LIBUKDEBUG_BASE)/include LIBUKDEBUG_ASINCLUDES-y += -I$(LIBUKDEBUG_BASE)/arch/$(CONFIG_UK_ARCH) LIBUKDEBUG_CINCLUDES-y += -I$(LIBUKDEBUG_BASE)/arch/$(CONFIG_UK_ARCH) -LIBUKDEBUG_CFLAGS-y += -D__IN_LIBUKDEBUG__ -LIBUKDEBUG_CXXFLAGS-y += -D__IN_LIBUKDEBUG__ - -LIBUKDEBUG_SRCS-y += $(LIBUKDEBUG_BASE)/print.c -LIBUKDEBUG_SRCS-$(CONFIG_HAVE_LIBC) += $(LIBUKDEBUG_BASE)/snprintf.c -LIBUKDEBUG_SRCS-y += $(LIBUKDEBUG_BASE)/outf.c -LIBUKDEBUG_SRCS-y += $(LIBUKDEBUG_BASE)/hexdump.c -LIBUKDEBUG_SRCS-$(CONFIG_LIBZYDIS) += $(LIBUKDEBUG_BASE)/asmdump.c - LIBUKDEBUG_SRCS-$(CONFIG_LIBUKDEBUG_GDBSTUB) += $(LIBUKDEBUG_BASE)/gdbstub.c|isr LIBUKDEBUG_SRCS-$(CONFIG_LIBUKDEBUG_GDBSTUB) += $(LIBUKDEBUG_BASE)/gdbtargetxml.ld LIBUKDEBUG_SRCS-$(CONFIG_LIBUKDEBUG_GDBSTUB) += $(LIBUKDEBUG_BASE)/gdbtargetxml.S diff --git a/lib/ukdebug/asmdump.c b/lib/ukdebug/asmdump.c deleted file mode 100644 index 105dd80e7a..0000000000 --- a/lib/ukdebug/asmdump.c +++ /dev/null @@ -1,194 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Dump disassembler output to kern/debug console - * - * Authors: Simon Kuenzer - * - * - * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include "outf.h" - -#if CONFIG_LIBZYDIS -#include - -/** - * Disassemble instructions with zydis starting - * with instruction at - */ -static int _asmdump(struct out_dev *o, - const void *instr, unsigned int count) -{ - ZydisDecoder dcr; - ZydisFormatter fmt; - ZydisDecodedInstruction ins; - char buf[128]; - int offset = 0; - int ret, total = 0; - __uptr addr = (__uptr) instr; - -#if __X86_32__ - if (!ZYAN_SUCCESS(ZydisDecoderInit(&dcr, - ZYDIS_MACHINE_MODE_LONG_COMPAT_32, - ZYDIS_ADDRESS_WIDTH_32))) - return -1; -#elif __X86_64__ - if (!ZYAN_SUCCESS(ZydisDecoderInit(&dcr, - ZYDIS_MACHINE_MODE_LONG_64, - ZYDIS_ADDRESS_WIDTH_64))) - return -1; -#else -#error libzydis: Unsupported architecture -#endif - - if (!ZYAN_SUCCESS(ZydisFormatterInit(&fmt, - ZYDIS_FORMATTER_STYLE_ATT))) - return -1; - - while (count) { - addr = ((__uptr) instr) + offset; - if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&dcr, - (const void *) addr, - 16, &ins))) - break; - ZydisFormatterFormatInstruction(&fmt, &ins, buf, sizeof(buf), - addr); - ret = outf(o, "%08"__PRIuptr" <+%d>: %hs\n", addr, offset, buf); - if (ret < 0) - return ret; - - total += ret; - offset += ins.length; - count--; - } - - return total; -} - -/** - * Disassemble bytes with zydis starting - * with instruction at - */ -static int _asmndump(struct out_dev *o, - const void *instr, size_t len) -{ - ZydisDecoder dcr; - ZydisFormatter fmt; - ZydisDecodedInstruction ins; - char buf[128]; - int offset = 0; - int ret, total = 0; - __uptr addr = (__uptr) instr; - -#if __X86_32__ - if (!ZYAN_SUCCESS(ZydisDecoderInit(&dcr, - ZYDIS_MACHINE_MODE_LONG_COMPAT_32, - ZYDIS_ADDRESS_WIDTH_32))) - return -1; -#elif __X86_64__ - if (!ZYAN_SUCCESS(ZydisDecoderInit(&dcr, - ZYDIS_MACHINE_MODE_LONG_64, - ZYDIS_ADDRESS_WIDTH_64))) - return -1; -#else -#error libzydis: Unsupported architecture -#endif - - if (!ZYAN_SUCCESS(ZydisFormatterInit(&fmt, - ZYDIS_FORMATTER_STYLE_ATT))) - return -1; - - while (len) { - addr = ((__uptr) instr) + offset; - if (!ZYAN_SUCCESS(ZydisDecoderDecodeBuffer(&dcr, - (const void *) addr, - MIN(16u, len), - &ins))) - break; - ZydisFormatterFormatInstruction(&fmt, &ins, buf, sizeof(buf), - addr); - ret = outf(o, "%08"__PRIuptr" <+%d>: %hs\n", addr, offset, buf); - if (ret < 0) - return ret; - - total += ret; - offset += ins.length; - len -= ins.length; - } - - return total; -} -#else /* CONFIG_LIBZYDIS */ -#error No supported disassembler backend available. -#endif /* CONFIG_LIBZYDIS */ - -void _uk_asmdumpd(__u16 libid, const char *srcname, - unsigned int srcline, const void *instr, - unsigned int instr_count) -{ - struct out_dev o; - - out_dev_init_debug(&o, libid, srcname, srcline); - _asmdump(&o, instr, instr_count); -} - -void _uk_asmndumpd(__u16 libid, const char *srcname, - unsigned int srcline, const void *instr, - size_t len) -{ - struct out_dev o; - - out_dev_init_debug(&o, libid, srcname, srcline); - _asmndump(&o, instr, len); -} - -#if CONFIG_LIBUKDEBUG_PRINTK -void _uk_asmdumpk(int lvl, __u16 libid, - const char *srcname, unsigned int srcline, - const void *instr, unsigned int instr_count) -{ - struct out_dev o; - - out_dev_init_kern(&o, lvl, libid, srcname, srcline); - _asmdump(&o, instr, instr_count); -} - -void _uk_asmndumpk(int lvl, __u16 libid, - const char *srcname, unsigned int srcline, - const void *instr, size_t len) -{ - struct out_dev o; - - out_dev_init_kern(&o, lvl, libid, srcname, srcline); - _asmndump(&o, instr, len); -} -#endif /* CONFIG_LIBUKDEBUG_PRINTK */ diff --git a/lib/ukdebug/exportsyms.uk b/lib/ukdebug/exportsyms.uk index 6f001813ca..acbce219dd 100644 --- a/lib/ukdebug/exportsyms.uk +++ b/lib/ukdebug/exportsyms.uk @@ -1,15 +1,2 @@ -_uk_vprintd -_uk_printd -_uk_vprintk -_uk_printk -uk_hexdumpsn -uk_hexdumpf -uk_hexdumpd -_uk_hexdumpd -_uk_hexdumpk -_uk_asmdumpd -_uk_asmndumpd -_uk_asmdumpk -_uk_asmndumpk uk_trace_buffer_free uk_trace_buffer_writep diff --git a/lib/ukdebug/include/uk/asmdump.h b/lib/ukdebug/include/uk/asmdump.h deleted file mode 100644 index 323308b5b7..0000000000 --- a/lib/ukdebug/include/uk/asmdump.h +++ /dev/null @@ -1,162 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Dump disassembler output to kern/debug console - * - * Authors: Simon Kuenzer - * - * - * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __UKDEBUG_ASMDUMP__ -#define __UKDEBUG_ASMDUMP__ - -/** - * NOTE: Please note, this file defines only variants that print disassembler - * output to the KERN and DEBUG console: uk_asmdumpd(), ukasmdumpk(). - * They are intended for debugging purpose only because the calls get - * removed if there is no supported disassembler backend available - * (e.g., libzydis). - */ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * The following block is only enabled if supported backends are available. - * TODO: In order to add support for another backend library, extend this - * #if-condition and implement a printing handler (_asmdump()) - * in `asmdump.c` - */ -#if CONFIG_LIBZYDIS - -#ifdef __IN_LIBUKDEBUG__ -/* - * This redefinition of CONFIG_LIBUKDEBUG_PRINTD is doing the trick to - * switch on the correct declaration of uk_hexdumpd() when we are compiling - * this library and have the global debug switch CONFIG_LIBUKDEBUG_PRINTD - * not enabled. - */ -#if !defined CONFIG_LIBUKDEBUG_PRINTD || !CONFIG_LIBUKDEBUG_PRINTD -#undef CONFIG_LIBUKDEBUG_PRINTD -#define CONFIG_LIBUKDEBUG_PRINTD 1 -#endif -#endif /* __IN_LIBUKDEBUG__ */ - -#if (defined UK_DEBUG) || CONFIG_LIBUKDEBUG_PRINTD -/* Please use uk_asmdumpd() instead */ -void _uk_asmdumpd(__u16 libid, const char *srcname, - unsigned int srcline, const void *instr, - unsigned int instr_count); - -#define uk_asmdumpd(instr, instr_count) \ - _uk_asmdumpd(uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (instr), (instr_count)) - -void _uk_asmndumpd(__u16 libid, const char *srcname, - unsigned int srcline, const void *instr, - size_t len); - -#define uk_asmndumpd(instr, len) \ - _uk_asmndumpd(uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (instr), (len)) -#else /* (defined UK_DEBUG) || CONFIG_LIBUKDEBUG_PRINTD */ -static inline void uk_asmdumpd(const void *instr __unused, - unsigned int instr_count __unused) -{} - -static inline void uk_asmndumpd(const void *instr __unused, - size_t len __unused) -{} -#endif - -#if CONFIG_LIBUKDEBUG_PRINTK -/* Please use uk_asmdumpk() instead */ -void _uk_asmdumpk(int lvl, __u16 libid, const char *srcname, - unsigned int srcline, const void *instr, - unsigned int instr_count); - -#define uk_asmdumpk(lvl, instr, instr_count) \ - do { \ - if ((lvl) <= KLVL_MAX) \ - _uk_asmdumpk((lvl), uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (instr), (instr_count)); \ - } while (0) - -void _uk_asmndumpk(int lvl, __u16 libid, const char *srcname, - unsigned int srcline, const void *instr, - size_t len); - -#define uk_asmndumpk(lvl, instr, len) \ - do { \ - if ((lvl) <= KLVL_MAX) \ - _uk_asmdumpk((lvl), uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (instr), (len)); \ - } while (0) -#else /* CONFIG_LIBUKDEBUG_PRINTK */ -static inline void uk_asmdumpk(int lvl __unused, const void *instr __unused, - unsigned int instr_count __unused) -{} - -static inline void uk_asmndumpk(int lvl __unused, const void *instr __unused, - size_t len __unused) -{} -#endif /* CONFIG_LIBUKDEBUG_PRINTK */ - -#else /* Backends */ -/* - * In case there is no supported backend, we remove the asmdump(d|k) - * calls from the code: - */ -static inline void uk_asmdumpd(const void *instr __unused, - unsigned int instr_count __unused) -{} - -static inline void uk_asmndumpd(const void *instr __unused, - size_t len __unused) -{} - -static inline void uk_asmdumpk(int lvl __unused, const void *instr __unused, - unsigned int instr_count __unused) -{} - -static inline void uk_asmndumpk(int lvl __unused, const void *instr __unused, - size_t len __unused) -{} -#endif /* Backends */ - -#ifdef __cplusplus -} -#endif - -#endif /* __UKDEBUG_ASMDUMP__ */ diff --git a/lib/ukdebug/include/uk/print.h b/lib/ukdebug/include/uk/print.h deleted file mode 100644 index 72978cc355..0000000000 --- a/lib/ukdebug/include/uk/print.h +++ /dev/null @@ -1,249 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Debug printing routines - * - * Authors: Simon Kuenzer - * - * - * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __UKDEBUG_PRINT_H__ -#define __UKDEBUG_PRINT_H__ - -#include -#include -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef __BASENAME__ -#define __STR_BASENAME__ STRINGIFY(__BASENAME__) -#else -#define __STR_BASENAME__ (NULL) -#endif - -/* - * DEBUG PRINTING - */ -/* Internal debug print functions that are sometimes used - * by other libraries with an own debug print switch - * (e.g., hexdump, syscall_shim) - */ -void _uk_vprintd(__u16 libid, const char *srcname, - unsigned int srcline, const char *fmt, va_list ap); -void _uk_printd(__u16 libid, const char *srcname, - unsigned int srcline, const char *fmt, ...) __printf(4, 5); - -#ifdef __IN_LIBUKDEBUG__ -/* - * This redefinition of CONFIG_LIBUKDEBUG_PRINTD is doing the trick to avoid - * multiple declarations of uk_{v}printd() when we are compiling this library - * and have the global debug switch CONFIG_LIBUKDEBUG_PRINTD not enabled. - */ -#if !defined CONFIG_LIBUKDEBUG_PRINTD || !CONFIG_LIBUKDEBUG_PRINTD -#undef CONFIG_LIBUKDEBUG_PRINTD -#define CONFIG_LIBUKDEBUG_PRINTD 1 -#endif -#endif /* __IN_LIBUKDEBUG__ */ - -#if defined UK_DEBUG || CONFIG_LIBUKDEBUG_PRINTD -#define uk_vprintd(fmt, ap) \ - do { \ - _uk_vprintd(uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (fmt), ap); \ - } while (0) - -#define uk_vprintd_once(fmt, ap) \ - do { \ - static int __x; \ - if (unlikely(!__x)) { \ - _uk_vprintd(uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (fmt), ap); \ - __x = 1; \ - } \ - } while (0) - -#define uk_printd(fmt, ...) \ - do { \ - _uk_printd(uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (fmt), ##__VA_ARGS__); \ - } while (0) - -#define uk_printd_once(fmt, ...) \ - do { \ - static int __x; \ - if (unlikely(!__x)) { \ - _uk_printd(uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (fmt), ##__VA_ARGS__); \ - __x = 1; \ - } \ - } while (0) -#else -static inline void uk_vprintd(const char *fmt __unused, va_list ap __unused) -{} - -static inline void uk_printd(const char *fmt, ...) __printf(1, 2); -static inline void uk_printd(const char *fmt __unused, ...) -{} - -static inline void uk_vprintd_once(const char *fmt __unused, - va_list ap __unused) -{} - -static inline void uk_printd_once(const char *fmt, ...) __printf(1, 2); -static inline void uk_printd_once(const char *fmt __unused, ...) -{} -#endif - -/* - * KERNEL CONSOLE - */ -#define KLVL_INFO (3) -#define KLVL_WARN (2) -#define KLVL_ERR (1) -#define KLVL_CRIT (0) - -#if CONFIG_LIBUKDEBUG_PRINTK_CRIT -#define KLVL_MAX KLVL_CRIT -#elif CONFIG_LIBUKDEBUG_PRINTK_ERR -#define KLVL_MAX KLVL_ERR -#elif CONFIG_LIBUKDEBUG_PRINTK_WARN -#define KLVL_MAX KLVL_WARN -#elif CONFIG_LIBUKDEBUG_PRINTK_INFO -#define KLVL_MAX KLVL_INFO -#else -#define KLVL_MAX KLVL_ERR /* default level */ -#endif - -#if CONFIG_LIBUKDEBUG_PRINTK -/* please use the uk_printd(), uk_vprintd() macros because - * they compile in the function calls only if the configured - * debug level requires it - */ -void _uk_vprintk(int lvl, __u16 libid, const char *srcname, - unsigned int srcline, const char *fmt, va_list ap); -void _uk_printk(int lvl, __u16 libid, const char *srcname, - unsigned int srcline, const char *fmt, ...) __printf(5, 6); - -#define uk_vprintk(lvl, fmt, ap) \ - do { \ - if ((lvl) <= KLVL_MAX) \ - _uk_vprintk((lvl), uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (fmt), ap); \ - } while (0) - -#define uk_vprintk_once(lvl, fmt, ap) \ - do { \ - if ((lvl) <= KLVL_MAX) { \ - static int __x; \ - if (unlikely(!__x)) { \ - _uk_vprintk((lvl), uk_libid_self(), \ - __STR_BASENAME__, \ - __LINE__, (fmt), ap); \ - __x = 1; \ - } \ - } \ - } while (0) - -#define uk_printk(lvl, fmt, ...) \ - do { \ - if ((lvl) <= KLVL_MAX) \ - _uk_printk((lvl), uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (fmt), ##__VA_ARGS__); \ - } while (0) - -#define uk_printk_once(lvl, fmt, ...) \ - do { \ - if ((lvl) <= KLVL_MAX) { \ - static int __x; \ - if (unlikely(!__x)) { \ - _uk_printk((lvl), uk_libid_self(), \ - __STR_BASENAME__, \ - __LINE__, (fmt), ##__VA_ARGS__); \ - __x = 1; \ - } \ - } \ - } while (0) -#else -static inline void uk_vprintk(int lvl __unused, const char *fmt __unused, - va_list ap __unused) -{} - -static inline void uk_printk(int lvl, const char *fmt, ...) __printf(2, 3); -static inline void uk_printk(int lvl __unused, const char *fmt __unused, ...) -{} - -static inline void uk_vprintk_once(int lvl __unused, const char *fmt __unused, - va_list ap __unused) -{} - -static inline void uk_printk_once(int lvl, const char *fmt, ...) __printf(2, 3); -static inline void uk_printk_once(int lvl __unused, - const char *fmt __unused, ...) -{} -#endif /* CONFIG_LIBUKDEBUG_PRINTK */ - -/* - * Convenience wrapper for uk_printk() and uk_printd() - * This is similar to the pr_* variants that you find in the Linux kernel - */ -#define uk_pr_debug(fmt, ...) uk_printd((fmt), ##__VA_ARGS__) -#define uk_pr_debug_once(fmt, ...) uk_printd_once((fmt), ##__VA_ARGS__) -#define uk_pr_info(fmt, ...) uk_printk(KLVL_INFO, (fmt), ##__VA_ARGS__) -#define uk_pr_info_once(fmt, ...) uk_printk_once(KLVL_INFO, (fmt), \ - ##__VA_ARGS__) -#define uk_pr_warn(fmt, ...) uk_printk(KLVL_WARN, (fmt), ##__VA_ARGS__) -#define uk_pr_warn_once(fmt, ...) uk_printk_once(KLVL_WARN, (fmt), \ - ##__VA_ARGS__) -#define uk_pr_err(fmt, ...) uk_printk(KLVL_ERR, (fmt), ##__VA_ARGS__) -#define uk_pr_err_once(fmt, ...) uk_printk_once(KLVL_ERR, (fmt), \ - ##__VA_ARGS__) -#define uk_pr_crit(fmt, ...) uk_printk(KLVL_CRIT, (fmt), ##__VA_ARGS__) -#define uk_pr_crit_once(fmt, ...) uk_printk_once(KLVL_CRIT, (fmt), \ - ##__VA_ARGS__) - -/* Warning for stubbed functions */ -#define UK_WARN_STUBBED() \ - uk_pr_warn_once("%s() stubbed\n", __func__) - -/* DEPRECATED: Please use UK_WARN_STUBBED instead */ -#ifndef WARN_STUBBED -#define WARN_STUBBED() \ - UK_WARN_STUBBED() -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* __UKDEBUG_PRINT_H__ */ diff --git a/lib/ukdebug/outf.c b/lib/ukdebug/outf.c deleted file mode 100644 index d882d81adf..0000000000 --- a/lib/ukdebug/outf.c +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Internal helper for text output redirection - * - * Authors: Simon Kuenzer - * - * - * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "outf.h" - -#include -#include -#include -#include "snprintf.h" - -int outf(struct out_dev *dev, const char *fmt, ...) -{ - int ret = 0; - size_t rem; - va_list ap; - - UK_ASSERT(dev); - - va_start(ap, fmt); - switch (dev->type) { - case OUTDEV_FILE: - /* Use standard libc approach when printing to a file */ - ret = vfprintf(dev->file.fp, fmt, ap); - break; - case OUTDEV_BUFFER: - ret = __uk_vsnprintf(dev->buffer.pos, dev->buffer.left, fmt, ap); - - if (ret > 0) { - rem = MIN(dev->buffer.left, (size_t)ret); - dev->buffer.pos += rem; - dev->buffer.left -= rem; - } - break; - case OUTDEV_DEBUG: - _uk_vprintd(dev->uk_pr.libid, - dev->uk_pr.srcname, dev->uk_pr.srcline, - fmt, ap); - break; -#if CONFIG_LIBUKDEBUG_PRINTK - case OUTDEV_KERN: - _uk_vprintk(dev->uk_pr.lvl, dev->uk_pr.libid, - dev->uk_pr.srcname, dev->uk_pr.srcline, - fmt, ap); - break; -#endif - default: - break; - } - va_end(ap); - - return ret; -} diff --git a/lib/ukdebug/outf.h b/lib/ukdebug/outf.h deleted file mode 100644 index 32da204a6e..0000000000 --- a/lib/ukdebug/outf.h +++ /dev/null @@ -1,115 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Internal helper for text output redirection - * - * Authors: Simon Kuenzer - * - * - * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __UKDEBUG_INTERNAL_OUTF_H__ -#define __UKDEBUG_INTERNAL_OUTF_H__ - -#include -#include -#include -#include - -enum out_dev_type { - OUTDEV_FILE = 0, - OUTDEV_BUFFER, -#if CONFIG_LIBUKDEBUG_PRINTK - OUTDEV_KERN, -#endif - OUTDEV_DEBUG, -}; - -struct out_dev { - enum out_dev_type type; - - union { - /* OUTDEV_KERN, OUTDEV_DEBUG */ - struct { - int lvl; /* OUTDEV_KERN only */ - __u16 libid; - const char *srcname; - unsigned int srcline; - } uk_pr; - - /* UK_HXDOUT_FILE */ - struct { - FILE *fp; - } file; - - /* UK_HXDOUT_BUFFER */ - struct { - char *pos; - size_t left; - } buffer; - }; -}; - -/** - * Sends a formatted string to a given output device - */ -int outf(struct out_dev *dev, const char *fmt, ...); - -#define out_dev_init_file(dev, fp) \ - do { \ - (dev)->type = OUTDEV_FILE; \ - (dev)->file.fp = (fp); \ - } while (0) - -#define out_dev_init_buffer(dev, addr, len) \ - do { \ - (dev)->type = OUTDEV_BUFFER; \ - (dev)->buffer.pos = (addr); \ - (dev)->buffer.left = (len); \ - } while (0) - -#if CONFIG_LIBUKDEBUG_PRINTK -#define out_dev_init_kern(dev, lvl, libid, srcname, srcline) \ - do { \ - (dev)->type = OUTDEV_KERN; \ - (dev)->uk_pr.lvl = (lvl); \ - (dev)->uk_pr.libid = (libid); \ - (dev)->uk_pr.srcname = (srcname); \ - (dev)->uk_pr.srcline = (srcline); \ - } while (0) -#endif - -#define out_dev_init_debug(dev, libid, srcname, srcline) \ - do { \ - (dev)->type = OUTDEV_DEBUG; \ - (dev)->uk_pr.libid = (libid); \ - (dev)->uk_pr.srcname = (srcname); \ - (dev)->uk_pr.srcline = (srcline); \ - } while (0) - -#endif /* __UKDEBUG_INTERNAL_OUTF_H__ */ diff --git a/lib/ukdebug/print.c b/lib/ukdebug/print.c deleted file mode 100644 index 48659c1821..0000000000 --- a/lib/ukdebug/print.c +++ /dev/null @@ -1,464 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Debug printing routines - * - * Authors: Simon Kuenzer - * - * - * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "snprintf.h" -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#if CONFIG_LIBUKDEBUG_PRINT_THREAD -#include -#endif - -#if CONFIG_LIBUKCONSOLE -#include -#include -#endif /* CONFIG_LIBUKCONSOLE */ - -#if CONFIG_LIBUKDEBUG_ANSI_COLOR -#define LVLC_RESET UK_ANSI_MOD_RESET -#define LVLC_TS UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_GREEN) -#define LVLC_CALLER UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_RED) -#define LVLC_THREAD UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_BLUE) -#define LVLC_LIBNAME UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_YELLOW) -#define LVLC_SRCNAME UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_CYAN) -#define LVLC_DEBUG UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_WHITE) -#define LVLC_KERN UK_ANSI_MOD_BOLD \ - UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_BLUE) -#define LVLC_INFO UK_ANSI_MOD_BOLD \ - UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_GREEN) -#define LVLC_WARN UK_ANSI_MOD_BOLD \ - UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_YELLOW) -#define LVLC_ERROR UK_ANSI_MOD_BOLD \ - UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_RED) -#define LVLC_ERROR_MSG UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_RED) -#define LVLC_CRIT UK_ANSI_MOD_BOLD \ - UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_WHITE) \ - UK_ANSI_MOD_COLORBG(UK_ANSI_COLOR_RED) - -#define LVLC_CRIT_MSG UK_ANSI_MOD_BOLD \ - UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_RED) -#else -#define LVLC_RESET "" -#define LVLC_TS "" -#define LVLC_CALLER "" -#define LVLC_THREAD "" -#define LVLC_LIBNAME "" -#define LVLC_SRCNAME "" -#define LVLC_DEBUG "" -#define LVLC_KERN "" -#define LVLC_INFO "" -#define LVLC_WARN "" -#define LVLC_ERROR "" -#define LVLC_ERROR_MSG "" -#define LVLC_CRIT "" -#define LVLC_CRIT_MSG "" -#endif /* !CONFIG_LIBUKDEBUG_ANSI_COLOR */ - -#define BUFLEN 192 -/* special level for printk redirection, used internally only */ -#define KLVL_DEBUG (-1) - -typedef __ssz (*cout_func)(const char *buf, __sz len); - -struct _vprint_console { - cout_func cout; - int newline; - int prevlvl; -}; - -#if CONFIG_LIBUKCONSOLE -/* TODO: Some consoles require both a newline and a carriage return to - * go to the start of the next line. This kind of behavior should be in - * a single place in posix-tty. We keep this workaround until we have feature - * in posix-tty that handles newline characters correctly. - */ -static inline __ssz _console_out(const char *buf, __sz len) -{ - const char *next_nl = NULL; - __sz l = len; - __sz off = 0; - __ssz rc = 0; - - if (unlikely(!len)) - return 0; - if (unlikely(!buf)) - return -EINVAL; - - while (l > 0) { - next_nl = memchr(buf, '\n', l); - if (next_nl) { - off = next_nl - buf; - if ((rc = uk_console_out(buf, off)) < 0) - return rc; - if ((rc = uk_console_out("\r\n", 2)) < 0) - return rc; - buf = next_nl + 1; - l -= off + 1; - } else { - if ((rc = uk_console_out(buf, l)) < 0) - return rc; - break; - } - } - - return len; -} -#endif /* CONFIG_LIBUKCONSOLE */ - -/* Console state for kernel output */ -#if CONFIG_LIBUKDEBUG_REDIR_PRINTD || CONFIG_LIBUKDEBUG_PRINTK -static struct _vprint_console kern = { -#if CONFIG_LIBUKCONSOLE - .cout = _console_out, -#else - .cout = NULL, -#endif /* CONFIG_LIBUKCONSOLE */ - .newline = 1, - .prevlvl = INT_MIN -}; -#endif - -/* Console state for debug output */ -#if !CONFIG_LIBUKDEBUG_REDIR_PRINTD -static struct _vprint_console debug = { -#if CONFIG_LIBUKCONSOLE - .cout = _console_out, -#else - .cout = NULL, -#endif /* CONFIG_LIBUKCONSOLE */ - .newline = 1, - .prevlvl = INT_MIN -}; -#endif - -static inline void _vprint_cout(struct _vprint_console *cons, - const char *buf, __sz len) -{ - if (cons->cout) - cons->cout(buf, len); -} - -#if CONFIG_LIBUKDEBUG_PRINT_TIME -static void _print_timestamp(struct _vprint_console *cons) -{ - char buf[BUFLEN]; - int len; - __nsec nansec = ukplat_monotonic_clock(); - __nsec sec = ukarch_time_nsec_to_sec(nansec); - __nsec rem_usec = ukarch_time_subsec(nansec); - - rem_usec = ukarch_time_nsec_to_usec(rem_usec); - len = __uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_TS - "[%5" __PRInsec ".%06" __PRInsec "] ", - sec, rem_usec); - _vprint_cout(cons, (char *)buf, len); -} -#endif - -#if CONFIG_LIBUKDEBUG_PRINT_THREAD -static void _print_thread(struct _vprint_console *cons) -{ - struct uk_thread *t = uk_thread_current(); - char buf[BUFLEN]; - int len; - - if (t) { - if (t->name) { - len = __uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_THREAD - "<%s> ", t->name); - } else { - len = __uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_THREAD - "<%p> ", (void *) t); - } - } else { - len = __uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_THREAD - "<> "); - } - _vprint_cout(cons, (char *)buf, len); -} -#endif /* CONFIG_LIBUKDEBUG_PRINT_THREAD */ - -#if CONFIG_LIBUKDEBUG_PRINT_CALLER -static void _print_caller(struct _vprint_console *cons, __uptr ra, __uptr fa) -{ - char buf[BUFLEN]; - int len; - - len = __uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_CALLER - "{r:%p,f:%p} ", (void *) ra, (void *) fa); - _vprint_cout(cons, (char *)buf, len); -} -#endif /* CONFIG_LIBUKDEBUG_PRINT_CALLER */ - -static void _vprint(struct _vprint_console *cons, - int lvl, __u16 libid, -#if CONFIG_LIBUKDEBUG_PRINT_SRCNAME - const char *srcname, - unsigned int srcline, -#endif /* CONFIG_LIBUKDEBUG_PRINT_SRCNAME */ -#if CONFIG_LIBUKDEBUG_PRINT_CALLER - __uptr retaddr, - __uptr frameaddr, -#endif /* CONFIG_LIBUKDEBUG_PRINT_CALLER */ - const char *fmt, va_list ap) -{ - char lbuf[BUFLEN]; - int len, llen; - const char *msghdr = NULL; - const char *lptr = NULL; - const char *nlptr = NULL; - const char *libname = uk_libname(libid); - - /* - * Note: We reset the console colors earlier in order to exclude - * background colors for trailing white spaces. - */ - switch (lvl) { - case KLVL_DEBUG: - msghdr = LVLC_RESET LVLC_DEBUG "dbg:" LVLC_RESET " "; - break; - case KLVL_CRIT: - msghdr = LVLC_RESET LVLC_CRIT "CRIT:" LVLC_RESET " "; - break; - case KLVL_ERR: - msghdr = LVLC_RESET LVLC_ERROR "ERR:" LVLC_RESET " "; - break; - case KLVL_WARN: - msghdr = LVLC_RESET LVLC_WARN "Warn:" LVLC_RESET " "; - break; - case KLVL_INFO: - msghdr = LVLC_RESET LVLC_INFO "Info:" LVLC_RESET " "; - break; - default: - /* unknown type: ignore */ - return; - } - - if (lvl != cons->prevlvl) { - /* level changed from previous call */ - if (cons->prevlvl != INT_MIN && !cons->newline) { - /* level changed without closing with '\n', - * enforce printing '\n', before the new message header - */ - _vprint_cout(cons, "\n", 1); - } - cons->prevlvl = lvl; - cons->newline = 1; /* enforce printing the message header */ - } - - len = __uk_vsnprintf(lbuf, BUFLEN, fmt, ap); - lptr = lbuf; - while (len > 0) { - if (cons->newline) { -#if CONFIG_LIBUKDEBUG_PRINT_TIME - _print_timestamp(cons); -#endif - _vprint_cout(cons, DECONST(char *, msghdr), - strlen(msghdr)); -#if CONFIG_LIBUKDEBUG_PRINT_THREAD - _print_thread(cons); -#endif -#if CONFIG_LIBUKDEBUG_PRINT_CALLER - _print_caller(cons, retaddr, frameaddr); -#endif - if (libname) { - _vprint_cout(cons, LVLC_RESET LVLC_LIBNAME "[", - strlen(LVLC_RESET LVLC_LIBNAME) + 1); - _vprint_cout(cons, DECONST(char *, libname), - strlen(libname)); - _vprint_cout(cons, "] ", 2); - } -#if CONFIG_LIBUKDEBUG_PRINT_SRCNAME - if (srcname) { - char lnobuf[6]; - - _vprint_cout(cons, LVLC_RESET LVLC_SRCNAME "<", - strlen(LVLC_RESET LVLC_SRCNAME) + 1); - _vprint_cout(cons, DECONST(char *, srcname), - strlen(srcname)); - _vprint_cout(cons, " @ ", 3); - _vprint_cout(cons, lnobuf, - __uk_snprintf(lnobuf, - sizeof(lnobuf), - "%4u", srcline)); - _vprint_cout(cons, "> ", 2); - } -#endif - cons->newline = 0; - } - - nlptr = memchr(lptr, '\n', len); - if (nlptr) { - llen = (int)((uintptr_t)nlptr - (uintptr_t)lptr) + 1; - cons->newline = 1; - } else { - llen = len; - } - - /* Message body */ - switch (lvl) { - case KLVL_CRIT: - _vprint_cout(cons, LVLC_RESET LVLC_CRIT_MSG, - strlen(LVLC_RESET LVLC_CRIT_MSG)); - break; - case KLVL_ERR: - _vprint_cout(cons, LVLC_RESET LVLC_ERROR_MSG, - strlen(LVLC_RESET LVLC_ERROR_MSG)); - break; - default: - _vprint_cout(cons, LVLC_RESET, strlen(LVLC_RESET)); - } - _vprint_cout(cons, (char *)lptr, llen); - _vprint_cout(cons, LVLC_RESET, strlen(LVLC_RESET)); - - len -= llen; - lptr = nlptr + 1; - } -} - -/* - * DEBUG PRINTING ENTRY - * uk_printd() and uk_vprintd are always compiled in. - * We rely on OPTIMIZE_DEADELIM: These symbols are automatically - * removed from the final image when there was no usage. - */ -#if CONFIG_LIBUKDEBUG_PRINT_SRCNAME -#define _VPRINT_ARGS_SRCNAME(srcname, srcline) \ - (srcname), (srcline), -#else -#define _VPRINT_ARGS_SRCNAME(srcname, srcline) -#endif /* CONFIG_LIBUKDEBUG_PRINT_SRCNAME */ - -#if CONFIG_LIBUKDEBUG_PRINT_CALLER -#define _VPRINT_ARGS_CALLER() \ - __return_addr(0), \ - __frame_addr(0), -#else -#define _VPRINT_ARGS_CALLER() -#endif /* CONFIG_LIBUKDEBUG_PRINT_CALLER */ - -void _uk_vprintd(__u16 libid, const char *srcname __maybe_unused, - unsigned int srcline __maybe_unused, const char *fmt, - va_list ap) -{ - -#if CONFIG_LIBUKDEBUG_REDIR_PRINTD - _vprint(&kern, KLVL_DEBUG, libid, - _VPRINT_ARGS_SRCNAME(srcname, srcline) - _VPRINT_ARGS_CALLER() - fmt, ap); -#else - _vprint(&debug, KLVL_DEBUG, libid, - _VPRINT_ARGS_SRCNAME(srcname, srcline) - _VPRINT_ARGS_CALLER() - fmt, ap); -#endif /* !CONFIG_LIBUKDEBUG_REDIR_PRINTD */ -} - -void _uk_printd(__u16 libid, const char *srcname __maybe_unused, - unsigned int srcline __maybe_unused, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); -#if CONFIG_LIBUKDEBUG_REDIR_PRINTD - _vprint(&kern, KLVL_DEBUG, libid, - _VPRINT_ARGS_SRCNAME(srcname, srcline) - _VPRINT_ARGS_CALLER() - fmt, ap); -#else - _vprint(&debug, KLVL_DEBUG, libid, - _VPRINT_ARGS_SRCNAME(srcname, srcline) - _VPRINT_ARGS_CALLER() - fmt, ap); -#endif /* !CONFIG_LIBUKDEBUG_REDIR_PRINTD */ - va_end(ap); -} - -/* - * KERNEL PRINT ENTRY - * Different to uk_printd(), we have a global switch that disables kernel - * messages. We compile these entry points only in when the kernel console is - * enabled. - */ -#if CONFIG_LIBUKDEBUG_PRINTK -void _uk_vprintk(int lvl, __u16 libid, - const char *srcname __maybe_unused, - unsigned int srcline __maybe_unused, - const char *fmt, va_list ap) -{ -#if CONFIG_LIBUKDEBUG_REDIR_PRINTK - _vprint(&debug, lvl, libid, - _VPRINT_ARGS_SRCNAME(srcname, srcline) - _VPRINT_ARGS_CALLER() - fmt, ap); -#else - _vprint(&kern, lvl, libid, - _VPRINT_ARGS_SRCNAME(srcname, srcline) - _VPRINT_ARGS_CALLER() - fmt, ap); -#endif /* !CONFIG_LIBUKDEBUG_REDIR_PRINTK */ -} - -void _uk_printk(int lvl, __u16 libid, - const char *srcname __maybe_unused, - unsigned int srcline __maybe_unused, - const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); -#if CONFIG_LIBUKDEBUG_REDIR_PRINTK - _vprint(&debug, lvl, libid, - _VPRINT_ARGS_SRCNAME(srcname, srcline) - _VPRINT_ARGS_CALLER() - fmt, ap); -#else - _vprint(&kern, lvl, libid, - _VPRINT_ARGS_SRCNAME(srcname, srcline) - _VPRINT_ARGS_CALLER() - fmt, ap); -#endif /* !CONFIG_LIBUKDEBUG_REDIR_PRINTK */ - va_end(ap); -} -#endif /* CONFIG_LIBUKDEBUG_PRINTD */ diff --git a/lib/ukdebug/snprintf.h b/lib/ukdebug/snprintf.h deleted file mode 100644 index edebb52c6e..0000000000 --- a/lib/ukdebug/snprintf.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Authors: Simon Kuenzer - * - * - * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __UKDEBUG_INTERNAL_SNPRINTF_H__ -#define __UKDEBUG_INTERNAL_SNPRINTF_H__ - -#include - -/* - * Point __uk_(v)snprintf to library-internal implementation as soon as - * we do not use lib/nolibc as libc. - */ -#if CONFIG_LIBNOLIBC -#include - -#define __uk_vsnprintf(...) vsnprintf(__VA_ARGS__) -#define __uk_snprintf(...) snprintf(__VA_ARGS__) - -#else /* CONFIG_LIBNOLIBC */ -#include -#include -#include - -int __uk_vsnprintf(char *str, size_t size, const char *fmt, va_list ap); -int __uk_snprintf(char *str, size_t size, const char *fmt, ...) __printf(3, 4); - -#endif /* CONFIG_LIBNOLIBC */ - -#endif /* __UKDEBUG_INTERNAL_SNPRINTF_H__ */ diff --git a/lib/ukprint/Config.uk b/lib/ukprint/Config.uk new file mode 100644 index 0000000000..0ac761a6f1 --- /dev/null +++ b/lib/ukprint/Config.uk @@ -0,0 +1,98 @@ +menuconfig LIBUKPRINT + bool "ukprint: Printing and logging facilities" + select LIBNOLIBC if !HAVE_LIBC + select LIBUKBITOPS + default y + +if LIBUKPRINT + +choice + prompt "Kernel verbosity" + default LIBUKPRINT_KLVL_ERR + depends on LIBUKPRINT_PRINTK + help + Set the level of detail of kernel messages + +config LIBUKPRINT_KLVL_DEBUG + bool "Debug" + +config LIBUKPRINT_KLVL_INFO + bool "Info" + +config LIBUKPRINT_KLVL_WARN + bool "Warn" + +config LIBUKPRINT_KLVL_ERR + bool "Error (default)" + +config LIBUKPRINT_KLVL_CRIT + bool "Critical" +endchoice + +menuconfig LIBUKPRINT_PRINTK + bool "Enable kernel messages (uk_printk)" + default y + help + Enables kernel message console. + +if LIBUKPRINT_PRINTK + +config LIBUKPRINT_PRINT_TIME + bool "Show timestamp in messages" + default y + +config LIBUKPRINT_PRINT_THREAD + bool "Show thread identifier" + depends on LIBUKSCHED + help + Prints the thread name or, if unnamed, the address of + the TCB (struct uk_thread) of the currently scheduled + thread. For the case `uk_thread_current()` returns + NULL, the placeholder "<>" is printed instead. + +config LIBUKPRINT_PRINT_CALLER + bool "Show caller information" + help + Prints the current return address and current stack frame + address for the message command. The return address can be + useful in combination with a debugger. The stack frame + address is a handy information for analysing the state of + the currently active stack. + Format: "{r:,f:}" + +config LIBUKPRINT_PRINT_SRCNAME + bool "Print source code location of messages" + default y + +config LIBUKPRINT_ANSI_COLOR + bool "Colored output" + help + Use ANSI control sequences to colorize console output. + Before activating this option, please make sure that + your console output/display supports ANSI. + +config LIBUKPRINT_PRINTK_UKSTORE + bool "Control verbosity via ukstore" + select LIBUKSTORE + help + Allows configuring the console verbosity at runtime via ukstore. + The maximum verbosity is still bound to the highest verbosity + level configured at compile time. + +endif + +menuconfig LIBUKPRINT_LOGBUF + bool "Kernel log buffer (dmesg)" + select LIBUKLOCK + help + TODO + +if LIBUKPRINT_LOGBUF + +config LIBUKPRINT_LOGBUF_SIZE + int "Log buffer max message length (chars)" + default 10240 + +endif + +endif diff --git a/lib/ukprint/Makefile.uk b/lib/ukprint/Makefile.uk new file mode 100644 index 0000000000..cf8d662684 --- /dev/null +++ b/lib/ukprint/Makefile.uk @@ -0,0 +1,12 @@ +$(eval $(call addlib_s,libukprint,$(CONFIG_LIBUKPRINT))) + +CINCLUDES-y += -I$(LIBUKPRINT_BASE)/include +CXXINCLUDES-y += -I$(LIBUKPRINT_BASE)/include + +LIBUKPRINT_SRCS-y += $(LIBUKPRINT_BASE)/print.c +LIBUKPRINT_SRCS-$(CONFIG_HAVE_LIBC) += $(LIBUKPRINT_BASE)/snprintf.c +LIBUKPRINT_SRCS-y += $(LIBUKPRINT_BASE)/outf.c +LIBUKPRINT_SRCS-y += $(LIBUKPRINT_BASE)/hexdump.c +LIBUKPRINT_SRCS-$(CONFIG_LIBUKCONSOLE) += $(LIBUKPRINT_BASE)/console.c +LIBUKPRINT_SRCS-$(CONFIG_LIBUKPRINT_LOGBUF) += $(LIBUKPRINT_BASE)/logbuf.c +LIBUKPRINT_SRCS-$(CONFIG_LIBUKPRINT_PRINTK_UKSTORE) += $(LIBUKPRINT_BASE)/store.c diff --git a/lib/ukprint/console.c b/lib/ukprint/console.c new file mode 100644 index 0000000000..ac75d1bfee --- /dev/null +++ b/lib/ukprint/console.c @@ -0,0 +1,313 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#include "snprintf.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#if CONFIG_LIBUKPRINT_PRINT_THREAD +#include +#endif + +#if CONFIG_LIBUKCONSOLE +#include +#include +#endif /* CONFIG_LIBUKCONSOLE */ + +#include "uk_print_msg.h" + +unsigned int uk_print_console_lvl = UK_PRINT_KLVL_MAX; + +#if CONFIG_LIBUKPRINT_ANSI_COLOR +#define LVLC_RESET UK_ANSI_MOD_RESET +#define LVLC_TS UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_GREEN) +#define LVLC_CALLER UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_RED) +#define LVLC_THREAD UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_BLUE) +#define LVLC_LIBNAME UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_YELLOW) +#define LVLC_SRCNAME UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_CYAN) +#define LVLC_DEBUG UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_WHITE) +#define LVLC_KERN UK_ANSI_MOD_BOLD \ + UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_BLUE) +#define LVLC_INFO UK_ANSI_MOD_BOLD \ + UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_GREEN) +#define LVLC_WARN UK_ANSI_MOD_BOLD \ + UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_YELLOW) +#define LVLC_ERROR UK_ANSI_MOD_BOLD \ + UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_RED) +#define LVLC_ERROR_MSG UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_RED) +#define LVLC_CRIT UK_ANSI_MOD_BOLD \ + UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_WHITE) \ + UK_ANSI_MOD_COLORBG(UK_ANSI_COLOR_RED) + +#define LVLC_CRIT_MSG UK_ANSI_MOD_BOLD \ + UK_ANSI_MOD_COLORFG(UK_ANSI_COLOR_RED) +#else +#define LVLC_RESET "" +#define LVLC_TS "" +#define LVLC_CALLER "" +#define LVLC_THREAD "" +#define LVLC_LIBNAME "" +#define LVLC_SRCNAME "" +#define LVLC_DEBUG "" +#define LVLC_KERN "" +#define LVLC_INFO "" +#define LVLC_WARN "" +#define LVLC_ERROR "" +#define LVLC_ERROR_MSG "" +#define LVLC_CRIT "" +#define LVLC_CRIT_MSG "" +#endif /* !CONFIG_LIBUKPRINT_ANSI_COLOR */ + +#define BUFLEN 192 + +typedef __ssz (*cout_func)(const char *buf, __sz len); + +struct vprint_console { + cout_func cout; + int newline; + int prevlvl; +}; + +#if CONFIG_LIBUKCONSOLE +/* TODO: Some consoles require both a newline and a carriage return to + * go to the start of the next line. This kind of behavior should be in + * a single place in posix-tty. We keep this workaround until we have feature + * in posix-tty that handles newline characters correctly. + */ +static inline __ssz console_out(const char *buf, __sz len) +{ + const char *next_nl = NULL; + __sz l = len; + __sz off = 0; + __ssz rc = 0; + + if (unlikely(!len)) + return 0; + if (unlikely(!buf)) + return -EINVAL; + + while (l > 0) { + next_nl = memchr(buf, '\n', l); + if (next_nl) { + off = next_nl - buf; + if ((rc = uk_console_out(buf, off)) < 0) + return rc; + if ((rc = uk_console_out("\r\n", 2)) < 0) + return rc; + buf = next_nl + 1; + l -= off + 1; + } else { + if ((rc = uk_console_out(buf, l)) < 0) + return rc; + break; + } + } + + return len; +} +#endif /* CONFIG_LIBUKCONSOLE */ + +/* Console state for kernel output */ +static struct vprint_console kconsole = { +#if CONFIG_LIBUKCONSOLE + .cout = console_out, +#else + .cout = NULL, +#endif /* CONFIG_LIBUKCONSOLE */ + .newline = 1, + .prevlvl = INT_MIN +}; + +static inline void vprint_cout(struct vprint_console *cons, + const char *buf, __sz len) +{ + if (cons->cout) + cons->cout(buf, len); +} + +#if CONFIG_LIBUKPRINT_PRINT_TIME +static void print_timestamp(struct vprint_console *cons) +{ + char buf[BUFLEN]; + int len; + __nsec nansec = ukplat_monotonic_clock(); + __nsec sec = ukarch_time_nsec_to_sec(nansec); + __nsec rem_usec = ukarch_time_subsec(nansec); + + rem_usec = ukarch_time_nsec_to_usec(rem_usec); + len = uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_TS + "[%5" __PRInsec ".%06" __PRInsec "] ", + sec, rem_usec); + vprint_cout(cons, (char *)buf, len); +} +#endif + +#if CONFIG_LIBUKPRINT_PRINT_THREAD +static void print_thread(struct vprint_console *cons) +{ + struct uk_thread *t = uk_thread_current(); + char buf[BUFLEN]; + int len; + + if (t) { + if (t->name) { + len = uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_THREAD + "<%s> ", t->name); + } else { + len = uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_THREAD + "<%p> ", (void *)t); + } + } else { + len = uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_THREAD + "<> "); + } + vprint_cout(cons, (char *)buf, len); +} +#endif /* CONFIG_LIBUKPRINT_PRINT_THREAD */ + +#if CONFIG_LIBUKPRINT_PRINT_CALLER +static void print_caller(struct vprint_console *cons, __uptr ra, __uptr fa) +{ + char buf[BUFLEN]; + int len; + + len = uk_snprintf(buf, BUFLEN, LVLC_RESET LVLC_CALLER + "{r:%p,f:%p} ", (void *)ra, (void *)fa); + vprint_cout(cons, (char *)buf, len); +} +#endif /* CONFIG_LIBUKPRINT_PRINT_CALLER */ + +void uk_print_console_write(struct uk_print_msg *msg) +{ + char lbuf[BUFLEN]; + int len, llen; + const char *msghdr = NULL; + const char *lptr = NULL; + const char *nlptr = NULL; + const char *libname = uk_libname(msg->libid); + int lvl = msg->flags & UK_PRINT_KLVL_MASK; + int raw = msg->flags & UK_PRINT_RAW_MASK; + struct vprint_console *cons = &kconsole; + +#if CONFIG_LIBUKPRINT_PRINTK_UKSTORE + if (lvl > (int)uk_print_console_lvl) + return; +#endif /* CONFIG_LIBUKPRINT_PRINTK_UKSTORE */ + + /* + * Note: We reset the console colors earlier in order to exclude + * background colors for trailing white spaces. + */ + switch (lvl) { + case UK_PRINT_KLVL_DEBUG: + msghdr = LVLC_RESET LVLC_DEBUG "dbg:" LVLC_RESET " "; + break; + case UK_PRINT_KLVL_CRIT: + msghdr = LVLC_RESET LVLC_CRIT "CRIT:" LVLC_RESET " "; + break; + case UK_PRINT_KLVL_ERR: + msghdr = LVLC_RESET LVLC_ERROR "ERR:" LVLC_RESET " "; + break; + case UK_PRINT_KLVL_WARN: + msghdr = LVLC_RESET LVLC_WARN "Warn:" LVLC_RESET " "; + break; + case UK_PRINT_KLVL_INFO: + msghdr = LVLC_RESET LVLC_INFO "Info:" LVLC_RESET " "; + break; + default: /* KLVL_NONE: no header */ + msghdr = ""; + break; + } + + if (lvl != cons->prevlvl) { + /* level changed from previous call */ + if (cons->prevlvl != INT_MIN && !cons->newline) { + /* level changed without closing with '\n', + * enforce printing '\n', before the new message header + */ + vprint_cout(cons, "\n", 1); + } + cons->prevlvl = lvl; + cons->newline = 1; /* enforce printing the message header */ + } + + len = uk_vsnprintf(lbuf, BUFLEN, msg->fmt, msg->ap); + lptr = lbuf; + while (len > 0) { + if (cons->newline && !raw) { +#if CONFIG_LIBUKPRINT_PRINT_TIME + print_timestamp(cons); +#endif + vprint_cout(cons, DECONST(char *, msghdr), + strlen(msghdr)); +#if CONFIG_LIBUKPRINT_PRINT_THREAD + print_thread(cons); +#endif +#if CONFIG_LIBUKPRINT_PRINT_CALLER + print_caller(cons, msg->retaddr, msg->frameaddr); +#endif + if (libname) { + vprint_cout(cons, LVLC_RESET LVLC_LIBNAME "[", + strlen(LVLC_RESET LVLC_LIBNAME) + 1); + vprint_cout(cons, DECONST(char *, libname), + strlen(libname)); + vprint_cout(cons, "] ", 2); + } +#if CONFIG_LIBUKPRINT_PRINT_SRCNAME + if (msg->srcname) { + char lnobuf[6]; + + vprint_cout(cons, LVLC_RESET LVLC_SRCNAME "<", + strlen(LVLC_RESET LVLC_SRCNAME) + 1); + vprint_cout(cons, DECONST(char *, msg->srcname), + strlen(msg->srcname)); + vprint_cout(cons, " @ ", 3); + vprint_cout(cons, lnobuf, + uk_snprintf(lnobuf, sizeof(lnobuf), + "%4u", msg->srcline)); + vprint_cout(cons, "> ", 2); + } +#endif + cons->newline = 0; + } + + nlptr = memchr(lptr, '\n', len); + if (nlptr) { + llen = (int)((uintptr_t)nlptr - (uintptr_t)lptr) + 1; + cons->newline = 1; + } else { + llen = len; + } + + /* Message body */ + switch (lvl) { + case UK_PRINT_KLVL_CRIT: + vprint_cout(cons, LVLC_RESET LVLC_CRIT_MSG, + strlen(LVLC_RESET LVLC_CRIT_MSG)); + break; + case UK_PRINT_KLVL_ERR: + vprint_cout(cons, LVLC_RESET LVLC_ERROR_MSG, + strlen(LVLC_RESET LVLC_ERROR_MSG)); + break; + default: + vprint_cout(cons, LVLC_RESET, strlen(LVLC_RESET)); + } + vprint_cout(cons, (char *)lptr, llen); + vprint_cout(cons, LVLC_RESET, strlen(LVLC_RESET)); + + len -= llen; + lptr = nlptr + 1; + } +} diff --git a/lib/ukprint/exportsyms.uk b/lib/ukprint/exportsyms.uk new file mode 100644 index 0000000000..d899e9c8f8 --- /dev/null +++ b/lib/ukprint/exportsyms.uk @@ -0,0 +1,8 @@ +_uk_vprintk +_uk_printk +uk_hexdumpsn +uk_hexdumpf +uk_hexdumpd +_uk_hexdumpd +_uk_hexdumpk +uk_print_dmesg diff --git a/lib/ukdebug/hexdump.c b/lib/ukprint/hexdump.c similarity index 71% rename from lib/ukdebug/hexdump.c rename to lib/ukprint/hexdump.c index 21a588529c..8f8648ed7d 100644 --- a/lib/ukdebug/hexdump.c +++ b/lib/ukprint/hexdump.c @@ -1,36 +1,8 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Hexdump-like routines - * - * Authors: Simon Kuenzer - * - * +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. */ #include @@ -39,7 +11,7 @@ #include #include #include -#include +#include #define UK_HXDF_GRPFLAGS \ (UK_HXDF_GRPBYTE | UK_HXDF_GRPWORD | UK_HXDF_GRPDWORD \ @@ -241,26 +213,15 @@ int uk_hexdumpf(FILE *fp, const void *data, size_t len, size_t addr0, int flags, return _hxd(&o, data, len, addr0, flags, grps_per_line, line_prefix); } -void _uk_hexdumpd(__u16 libid, const char *srcname, - unsigned int srcline, const void *data, size_t len, - size_t addr0, int flags, unsigned int grps_per_line, - const char *line_prefix) -{ - struct out_dev o; - - out_dev_init_debug(&o, libid, srcname, srcline); - _hxd(&o, data, len, addr0, flags, grps_per_line, line_prefix); -} - -#if CONFIG_LIBUKDEBUG_PRINTK -void _uk_hexdumpk(int lvl, __u16 libid, const char *srcname, +#if CONFIG_LIBUKPRINT_PRINTK +void _uk_hexdumpk(int pflags, __u16 libid, const char *srcname, unsigned int srcline, const void *data, size_t len, size_t addr0, int flags, unsigned int grps_per_line, const char *line_prefix) { struct out_dev o; - out_dev_init_kern(&o, lvl, libid, srcname, srcline); + out_dev_init_kern(&o, pflags, libid, srcname, srcline); _hxd(&o, data, len, addr0, flags, grps_per_line, line_prefix); } #endif diff --git a/lib/ukprint/include/uk/print.h b/lib/ukprint/include/uk/print.h new file mode 100644 index 0000000000..96757110c1 --- /dev/null +++ b/lib/ukprint/include/uk/print.h @@ -0,0 +1,203 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#ifndef __UK_PRINT_H__ +#define __UK_PRINT_H__ + +#include + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __BASENAME__ +#define __STR_BASENAME__ STRINGIFY(__BASENAME__) +#else +#define __STR_BASENAME__ (NULL) +#endif + +/* Flags */ +#define UK_PRINT_KLVL_DEBUG 5 +#define UK_PRINT_KLVL_INFO 4 +#define UK_PRINT_KLVL_WARN 3 +#define UK_PRINT_KLVL_ERR 2 +#define UK_PRINT_KLVL_CRIT 1 +#define UK_PRINT_KLVL_NONE 0 /* print always */ + +#define UK_PRINT_RAW UK_BIT(16) /* no meta */ + +#define UK_PRINT_KLVL_MASK 0xff +#define UK_PRINT_RAW_MASK UK_PRINT_RAW + +#if CONFIG_LIBUKPRINT_KLVL_DEBUG +#define UK_PRINT_KLVL_MAX UK_PRINT_KLVL_DEBUG +#elif CONFIG_LIBUKPRINT_KLVL_CRIT +#define UK_PRINT_KLVL_MAX UK_PRINT_KLVL_CRIT +#elif CONFIG_LIBUKPRINT_KLVL_ERR +#define UK_PRINT_KLVL_MAX UK_PRINT_KLVL_ERR +#elif CONFIG_LIBUKPRINT_KLVL_WARN +#define UK_PRINT_KLVL_MAX UK_PRINT_KLVL_WARN +#elif CONFIG_LIBUKPRINT_KLVL_INFO +#define UK_PRINT_KLVL_MAX UK_PRINT_KLVL_INFO +#else +#define UK_PRINT_KLVL_MAX UK_PRINT_KLVL_ERR /* default level */ +#endif + +#if CONFIG_LIBUKPRINT +/* please use the uk_{v}printk() macros because they compile + * in the function calls only if the configured debug level + * requires it + */ +void _uk_vprintk(int flags, __u16 libid, const char *srcname, + unsigned int srcline, const char *fmt, va_list ap); +void _uk_printk(int flags, __u16 libid, const char *srcname, + unsigned int srcline, const char *fmt, ...) __printf(5, 6); + +#if defined UK_DEBUG +#define UK_PRINTK_EN(_flags) \ + ((((_flags) & UK_PRINT_KLVL_MASK) <= UK_PRINT_KLVL_MAX) || \ + (((_flags) & UK_PRINT_KLVL_MASK) == UK_PRINT_KLVL_DEBUG)) +#else /* !defined UK_DEBUG */ +#define UK_PRINTK_EN(_flags) \ + (((_flags) & UK_PRINT_KLVL_MASK) <= UK_PRINT_KLVL_MAX) +#endif /* !defined UK_DEBUG */ + +#define uk_vprintk(flags, fmt, ap) \ + do { \ + if (UK_PRINTK_EN(flags)) \ + _uk_vprintk((flags), uk_libid_self(), __STR_BASENAME__,\ + __LINE__, (fmt), ap); \ + } while (0) + +#define uk_vprintk_once(flags, fmt, ap) \ + do { \ + if (UK_PRINTK_EN(flags)) { \ + static int __x; \ + if (unlikely(!__x)) { \ + _uk_vprintk((flags), uk_libid_self(), \ + __STR_BASENAME__, \ + __LINE__, (fmt), ap); \ + __x = 1; \ + } \ + } \ + } while (0) + +#define uk_printk(flags, fmt, ...) \ + do { \ + if (UK_PRINTK_EN(flags)) \ + _uk_printk((flags), uk_libid_self(), __STR_BASENAME__, \ + __LINE__, (fmt), ##__VA_ARGS__); \ + } while (0) + +#define uk_printk_once(flags, fmt, ...) \ + do { \ + if (UK_PRINTK_EN(flags)) { \ + static int __x; \ + if (unlikely(!__x)) { \ + _uk_printk((flags), uk_libid_self(), \ + __STR_BASENAME__, \ + __LINE__, (fmt), ##__VA_ARGS__); \ + __x = 1; \ + } \ + } \ + } while (0) +#else /* !(CONFIG_LIBUKPRINT_PRINTK) */ +static inline void _uk_vprintk(int flags __unused, __u16 libid __unused, + const char *srcname __unused, + unsigned int srcline __unused, + const char *fmt __unused, va_list ap __unused) +{} + +static inline void _uk_printk(int flags, __u16 libid, const char *srcname, + unsigned int srcline, const char *fmt, ...) + __printf(5, 6); +static inline void _uk_printk(int flags __unused, __u16 libid __unused, + const char *srcname __unused, + unsigned int srcline __unused, + const char *fmt __unused, ...) +{} + +static inline void uk_vprintk(int flags __unused, const char *fmt __unused, + va_list ap __unused) +{} + +static inline void uk_printk(int flags, const char *fmt, ...) __printf(2, 3); +static inline void uk_printk(int flags __unused, const char *fmt __unused, ...) +{} + +static inline void uk_vprintk_once(int flags __unused, const char *fmt __unused, + va_list ap __unused) +{} + +static inline void uk_printk_once(int flags, const char *fmt, ...) __printf(2, 3); +static inline void uk_printk_once(int flags __unused, + const char *fmt __unused, ...) +{} +#endif /* !(CONFIG_LIBUKPRINT_PRINTK) */ + +/* + * Convenience wrappers for uk_printk(). This is similar to the + * pr_* variants that you find in the Linux kernel + */ +#define uk_pr_debug(fmt, ...) \ + uk_printk(UK_PRINT_KLVL_DEBUG, (fmt), ##__VA_ARGS__) + +#define uk_pr_debug_once(fmt, ...) \ + uk_printk_once(UK_PRINT_KLVL_DEBUG, (fmt), ##__VA_ARGS__) + +#define uk_pr_info(fmt, ...) \ + uk_printk(UK_PRINT_KLVL_INFO, (fmt), ##__VA_ARGS__) + +#define uk_pr_info_once(fmt, ...) \ + uk_printk_once(UK_PRINT_KLVL_INFO, (fmt), ##__VA_ARGS__) + +#define uk_pr_warn(fmt, ...) \ + uk_printk(UK_PRINT_KLVL_WARN, (fmt), ##__VA_ARGS__) + +#define uk_pr_warn_once(fmt, ...) \ + uk_printk_once(UK_PRINT_KLVL_WARN, (fmt), ##__VA_ARGS__) + +#define uk_pr_err(fmt, ...) \ + uk_printk(UK_PRINT_KLVL_ERR, (fmt), ##__VA_ARGS__) + +#define uk_pr_err_once(fmt, ...) \ + uk_printk_once(UK_PRINT_KLVL_ERR, (fmt), ##__VA_ARGS__) + +#define uk_pr_crit(fmt, ...) \ + uk_printk(UK_PRINT_KLVL_CRIT, (fmt), ##__VA_ARGS__) + +#define uk_pr_crit_once(fmt, ...) \ + uk_printk_once(UK_PRINT_KLVL_CRIT, (fmt), ##__VA_ARGS__) + +/* Warning for stubbed functions */ +#define UK_WARN_STUBBED() \ + uk_pr_warn_once("%s() stubbed\n", __func__) + +/* DEPRECATED: Please use UK_WARN_STUBBED instead */ +#ifndef WARN_STUBBED +#define WARN_STUBBED() \ + UK_WARN_STUBBED() +#endif + +#if CONFIG_LIBUKPRINT_LOGBUF +/** + * Print the log buffer's messages into console + */ +void uk_print_dmesg(void); +#endif /* CONFIG_LIBUKPRINT_LOGBUF */ + +#ifdef __cplusplus +} +#endif + +#endif /* __UK_PRINT_H__ */ diff --git a/lib/ukdebug/include/uk/hexdump.h b/lib/ukprint/include/uk/print/hexdump.h similarity index 59% rename from lib/ukdebug/include/uk/hexdump.h rename to lib/ukprint/include/uk/print/hexdump.h index 07add79236..0cf0bcec4c 100644 --- a/lib/ukdebug/include/uk/hexdump.h +++ b/lib/ukprint/include/uk/print/hexdump.h @@ -1,40 +1,12 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* - * Hexdump-like routines - * - * Authors: Simon Kuenzer - * - * +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. */ -#ifndef __UKDEBUG_HEXDUMP_H__ -#define __UKDEBUG_HEXDUMP_H__ +#ifndef __UK_PRINT_HEXDUMP_H__ +#define __UK_PRINT_HEXDUMP_H__ #include #include @@ -54,56 +26,9 @@ extern "C" { #define UK_HXDF_COMPRESS (64) /* suppress repeated lines */ -/* - * HEXDUMP ON DEBUG CONSOLE - */ -#ifdef __IN_LIBUKDEBUG__ -/* - * This redefinition of CONFIG_LIBUKDEBUG_PRINTD is doing the trick to - * switch on the correct declaration of uk_hexdumpd() when we are compiling - * this library and have the global debug switch CONFIG_LIBUKDEBUG_PRINTD - * not enabled. - */ -#if !defined CONFIG_LIBUKDEBUG_PRINTD || !CONFIG_LIBUKDEBUG_PRINTD -#undef CONFIG_LIBUKDEBUG_PRINTD -#define CONFIG_LIBUKDEBUG_PRINTD 1 -#endif -#endif /* __IN_LIBUKDEBUG__ */ - -#if (defined UK_DEBUG) || CONFIG_LIBUKDEBUG_PRINTD -/* Please use uk_hexdumpd() instead */ -void _uk_hexdumpd(__u16 libid, const char *srcname, - unsigned int srcline, const void *data, size_t len, - size_t addr0, int flags, unsigned int grps_per_line, - const char *line_prefix); - -/** - * Plots an hexdump for a given data region to kernel output - * The absolute address is plotted when UK_HXDF_ADDR is set - * - * @param lvl Debug level - * @param data Start of data region to plot - * @param len Length of data region (number of bytes) - * @param flags Format flags, see UK_HXDF_* - * @param grps_per_line Defines the number of bytes shown per line: - * Number of groups (UK_HXDF_GRP*) shown per line - * @return Returns the number of printed characters to output fp - */ -#define uk_hexdumpd(data, len, flags, grps_per_line) \ - _uk_hexdumpd(uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (data), (len), \ - ((size_t)(data)), (flags), \ - (grps_per_line), STRINGIFY(data) ": ") -#else /* (defined UK_DEBUG) || CONFIG_LIBUKDEBUG_PRINTD */ -static inline void uk_hexdumpd(const void *data __unused, size_t len __unused, - int flags __unused, - unsigned int grps_per_line __unused) -{} -#endif /* (defined UK_DEBUG) || CONFIG_LIBUKDEBUG_PRINTD */ - -#if CONFIG_LIBUKDEBUG_PRINTK +#if CONFIG_LIBUKPRINT_PRINTK /* Please use uk_hexdumpk() instead */ -void _uk_hexdumpk(int lvl, __u16 libid, const char *srcname, +void _uk_hexdumpk(int pflags, __u16 libid, const char *srcname, unsigned int srcline, const void *data, size_t len, size_t addr0, int flags, unsigned int grps_per_line, const char *line_prefix); @@ -112,7 +37,7 @@ void _uk_hexdumpk(int lvl, __u16 libid, const char *srcname, * Plots an hexdump for a given data region to kernel output * The absolute address is plotted when UK_HXDF_ADDR is set * - * @param lvl Debug level + * @param pflags Print flags * @param data Start of data region to plot * @param len Length of data region (number of bytes) * @param flags Format flags, see UK_HXDF_* @@ -120,20 +45,15 @@ void _uk_hexdumpk(int lvl, __u16 libid, const char *srcname, * Number of groups (UK_HXDF_GRP*) shown per line * @return Returns the number of printed characters to output fp */ -#define uk_hexdumpk(lvl, data, len, flags, grps_per_line) \ +#define uk_hexdumpk(pflags, data, len, flags, grps_per_line) \ do { \ - if ((lvl) <= KLVL_MAX) \ - _uk_hexdumpk((lvl), uk_libid_self(), __STR_BASENAME__, \ - __LINE__, (data), (len), \ + if (((pflags) & UK_PRINT_KLVL_MASK) <= UK_PRINT_KLVL_MAX) \ + _uk_hexdumpk((pflags), uk_libid_self(), \ + __STR_BASENAME__, __LINE__, \ + (data), (len), \ ((size_t)(data)), (flags), \ (grps_per_line), STRINGIFY(data) ": "); \ } while (0) -#else /* CONFIG_LIBUKDEBUG_PRINTK */ -static inline void uk_hexdumpk(int lvl __unused, const void *data __unused, - size_t len __unused, int flags __unused, - unsigned int grps_per_line __unused) -{} -#endif /* CONFIG_LIBUKDEBUG_PRINTK */ /** * Plots an hexdump for a given data region to a file descriptor @@ -171,6 +91,13 @@ int uk_hexdumpsn(char *str, size_t size, const void *data, size_t len, size_t addr0, int flags, unsigned int grps_per_line, const char *line_prefix); +#else /* !CONFIG_LIBUKPRINT_PRINTK */ +static inline void uk_hexdumpk(int pflags __unused, const void *data __unused, + size_t len __unused, int flags __unused, + unsigned int grps_per_line __unused) +{} +#endif /* !CONFIG_LIBUKPRINT_PRINTK */ + /** * Plots an hexdump for a given data region to a string buffer of unlimited size * @@ -210,13 +137,9 @@ int uk_hexdumpsn(char *str, size_t size, const void *data, size_t len, * Shortcuts for all hexdump variants ahead. The shortcuts use a similar style * as the hexdump Unix command using -C parameter: hexdump -C */ -#define uk_hexdumpCd(data, len) \ - uk_hexdumpd((data), (len), (UK_HXDF_ADDR | UK_HXDF_ASCIISEC \ - | UK_HXDF_GRPQWORD | UK_HXDF_COMPRESS), \ - 2) -#define uk_hexdumpCk(lvl, data, len) \ - uk_hexdumpk((lvl), (data), (len), \ +#define uk_hexdumpCk(pflags, data, len) \ + uk_hexdumpk((pflags), (data), (len), \ (UK_HXDF_ADDR | UK_HXDF_ASCIISEC | UK_HXDF_GRPQWORD \ | UK_HXDF_COMPRESS), \ 2) @@ -249,4 +172,4 @@ int uk_hexdumpsn(char *str, size_t size, const void *data, size_t len, } #endif -#endif /* __UKDEBUG_HEXDUMP_H__ */ +#endif /* __UK_PRINT_HEXDUMP_H__ */ diff --git a/lib/ukprint/include/uk/print/store.h b/lib/ukprint/include/uk/print/store.h new file mode 100644 index 0000000000..d7e2efcf9f --- /dev/null +++ b/lib/ukprint/include/uk/print/store.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#ifndef __UK_PRINT_STORE_H__ +#define __UK_PRINT_STORE_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* ukstore entry tha controls the verbosity at runtime. + * For values see UK_PRINT_KLVL_ in print.h + */ +#define UK_PRINT_KLVL_ENTRY_ID 1 + +#ifdef __cplusplus +} +#endif + +#endif /* __UK_PRINT_STORE_H__ */ diff --git a/lib/ukprint/logbuf.c b/lib/ukprint/logbuf.c new file mode 100644 index 0000000000..bfb969517c --- /dev/null +++ b/lib/ukprint/logbuf.c @@ -0,0 +1,144 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#include +#include + +#include +#include +#include + +#include "snprintf.h" +#include "uk_print_msg.h" + +#define LOGMSG_ALIGN 16 +#define LOGMSG_SIZE(_msg_len) (sizeof(struct uk_print_logmsg) + (_msg_len)) + +struct uk_print_logmsg { + struct uk_print_logmsg *next; + struct uk_print_msg msg; +}; + +static __u8 logbuf[CONFIG_LIBUKPRINT_LOGBUF_SIZE]; + +static struct uk_print_logmsg *logbuf_head; +static struct uk_print_logmsg *logbuf_tail; + +static uk_spinlock logbuf_lock = UK_SPINLOCK_INITIALIZER(); + +/* Returns the next free aligned position in the buffer, or wraps + * around. + */ +static inline __uptr logbuf_next(void) +{ + __uptr next; + + if (!logbuf_head) + return (__uptr)logbuf; + + next = ALIGN_UP((__uptr)logbuf_tail + LOGMSG_SIZE(logbuf_tail->msg.len), + LOGMSG_ALIGN); + + if (next >= (__uptr)logbuf + sizeof(logbuf)) + next = (__uptr)logbuf; + + return next; +} + +static inline void update_head(struct uk_print_logmsg *logmsg, __sz msg_len) +{ + struct uk_print_logmsg *lm; + int found = 0; /* bool */ + + if (RANGE_OVERLAP((__uptr)logbuf_head, LOGMSG_SIZE(logbuf_head->msg.len), + (__uptr)logmsg, LOGMSG_SIZE(msg_len))) { + for (lm = logbuf_head; lm != lm->next; lm = lm->next) { + if ((__uptr)lm->next > (__uptr)logmsg + LOGMSG_SIZE(msg_len)) { + logbuf_head = lm->next; + found = 1; + break; + } + } + + if (!found) { + /* This logmsg is the last element in the buffer. + * Set head to the first element. + */ + logbuf_head = (struct uk_print_logmsg *)logbuf; + } + } +} + +int uk_print_logbuf_write(struct uk_print_msg *msg) +{ + struct uk_print_logmsg *logmsg; + va_list cp; + + uk_spin_lock(&logbuf_lock); + + va_copy(cp, msg->ap); + msg->len = vsnprintf(msg->msg, 0, msg->fmt, cp); + msg->len++; /* NUL byte */ + + if (LOGMSG_SIZE(msg->len) > sizeof(logbuf)) { + uk_spin_unlock(&logbuf_lock); + return -EMSGSIZE; + } + + logmsg = (struct uk_print_logmsg *)logbuf_next(); + + /* If we exceed the buffer, wrap around */ + if ((__uptr)logmsg + LOGMSG_SIZE(msg->len) > (__uptr)logbuf + sizeof(logbuf)) + logmsg = (struct uk_print_logmsg *)logbuf; + + /* Update logbuf_head before we overwrite any message objects. + * The first needs to be checked / updated upon every new write + * after the first wraparound. + */ + if (logbuf_head) + update_head(logmsg, msg->len); + + memcpy(&logmsg->msg, msg, sizeof(*msg)); + + /* Format the message now. Once the caller returns, + * fmt and va_list will no longer be available. + */ + va_copy(cp, msg->ap); + vsnprintf(logmsg->msg.msg, msg->len, msg->fmt, cp); + + if (!logbuf_head) { + logbuf_head = logmsg; + logbuf_tail = logmsg; + } + logmsg->next = logmsg; + + logbuf_tail->next = logmsg; /* update previous last */ + logbuf_tail = logmsg; + + uk_spin_unlock(&logbuf_lock); + + return 0; +} + +void uk_print_dmesg(void) +{ +#if CONFIG_LIBUKCONSOLE + struct uk_print_logmsg *lm; + + uk_spin_lock(&logbuf_lock); + + if (!logbuf_head) { + uk_spin_unlock(&logbuf_lock); + return; + } + + for (lm = logbuf_head; lm != lm->next; lm = lm->next) + uk_console_out(lm->msg.msg, lm->msg.len); + uk_console_out(lm->msg.msg, lm->msg.len); + + uk_spin_unlock(&logbuf_lock); +#endif /* CONFIG_LIBUKCONSOLE */ +} diff --git a/lib/ukprint/outf.c b/lib/ukprint/outf.c new file mode 100644 index 0000000000..1f70cce190 --- /dev/null +++ b/lib/ukprint/outf.c @@ -0,0 +1,50 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#include "outf.h" + +#include +#include +#include +#include "snprintf.h" + +int outf(struct out_dev *dev, const char *fmt, ...) +{ + int ret = 0; + size_t rem; + va_list ap; + + UK_ASSERT(dev); + + va_start(ap, fmt); + switch (dev->type) { + case OUTDEV_FILE: + /* Use standard libc approach when printing to a file */ + ret = vfprintf(dev->file.fp, fmt, ap); + break; + case OUTDEV_BUFFER: + ret = uk_vsnprintf(dev->buffer.pos, dev->buffer.left, fmt, ap); + if (ret > 0) { + rem = MIN(dev->buffer.left, (size_t)ret); + dev->buffer.pos += rem; + dev->buffer.left -= rem; + } + break; +#if CONFIG_LIBUKPRINT_PRINTK + case OUTDEV_KERN: + _uk_vprintk(dev->uk_pr.flags, dev->uk_pr.libid, + dev->uk_pr.srcname, dev->uk_pr.srcline, + fmt, ap); + break; +#endif + default: + break; + } + va_end(ap); + + return ret; +} diff --git a/lib/ukprint/outf.h b/lib/ukprint/outf.h new file mode 100644 index 0000000000..bfaf1ec341 --- /dev/null +++ b/lib/ukprint/outf.h @@ -0,0 +1,78 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#ifndef __UK_PRINT_OUTF_H__ +#define __UK_PRINT_OUTF_H__ + +#include +#include +#include +#include + +enum out_dev_type { + OUTDEV_FILE = 0, + OUTDEV_BUFFER, +#if CONFIG_LIBUKPRINT_PRINTK + OUTDEV_KERN, +#endif +}; + +struct out_dev { + enum out_dev_type type; + + union { + /* OUTDEV_KERN */ + struct { + int flags; /* OUTDEV_KERN only */ + __u16 libid; + const char *srcname; + unsigned int srcline; + } uk_pr; + + /* UK_HXDOUT_FILE */ + struct { + FILE *fp; + } file; + + /* UK_HXDOUT_BUFFER */ + struct { + char *pos; + size_t left; + } buffer; + }; +}; + +/** + * Sends a formatted string to a given output device + */ +int outf(struct out_dev *dev, const char *fmt, ...); + +#define out_dev_init_file(dev, fp) \ + do { \ + (dev)->type = OUTDEV_FILE; \ + (dev)->file.fp = (fp); \ + } while (0) + +#define out_dev_init_buffer(dev, addr, len) \ + do { \ + (dev)->type = OUTDEV_BUFFER; \ + (dev)->buffer.pos = (addr); \ + (dev)->buffer.left = (len); \ + } while (0) + +#if CONFIG_LIBUKPRINT_PRINTK +#define out_dev_init_kern(dev, flgs, libid, srcname, srcline) \ + do { \ + (dev)->type = OUTDEV_KERN; \ + (dev)->uk_pr.flags = (flgs); \ + (dev)->uk_pr.libid = (libid); \ + (dev)->uk_pr.srcname = (srcname); \ + (dev)->uk_pr.srcline = (srcline); \ + } while (0) +#endif + +#endif /* __UK_PRINT_OUTF_H__ */ diff --git a/lib/ukprint/print.c b/lib/ukprint/print.c new file mode 100644 index 0000000000..915d2d0715 --- /dev/null +++ b/lib/ukprint/print.c @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#include +#include +#include +#include + +#include +#include + +#include "snprintf.h" +#include "uk_print_msg.h" + +#if CONFIG_LIBUKPRINT_PRINT_SRCNAME +#define UK_PRINT_MSG_ARGS_SRCNAME(_msg, _srcname, _srcline) \ + (_msg).srcname = (_srcname); \ + (_msg).srcline = (_srcline) +#else +#define UK_PRINT_MSG_ARGS_SRCNAME(_msg, _srcname, _srcline) +#endif /* CONFIG_LIBUKPRINT_PRINT_SRCNAME */ + +#if CONFIG_LIBUKPRINT_PRINT_CALLER +#define UK_PRINT_MSG_ARGS_CALLER(_msg) \ + (_msg).retaddr = __return_addr(0); \ + (_msg).frameaddr = __frame_addr(0) +#else +#define UK_PRINT_MSG_ARGS_CALLER(_msg) +#endif /* CONFIG_LIBUKPRINT_PRINT_CALLER */ + +#define UK_PRINT_MSG_ALLOC(_msg, _flags, _libid, _srcname, _srcline, \ + _fmt, _ap) \ + do { \ + (_msg) = (struct uk_print_msg) { \ + .flags = (_flags), \ + .libid = (_libid), \ + .fmt = (_fmt), \ + }; \ + UK_PRINT_MSG_ARGS_SRCNAME((_msg), (_srcname), \ + (_srcline)); \ + UK_PRINT_MSG_ARGS_CALLER((_msg)); \ + va_copy((_msg).ap, (_ap)); \ + } while (0) + +#define UK_PRINT_MSG_FREE(_msg) \ + va_end((_msg).ap) \ + +#if CONFIG_LIBUKPRINT_PRINTK +void _uk_vprintk(int flags, __u16 libid, + const char *srcname __maybe_unused, + unsigned int srcline __maybe_unused, + const char *fmt, va_list ap) +{ + struct uk_print_msg msg; + + UK_PRINT_MSG_ALLOC(msg, flags, libid, srcname, srcline, fmt, ap); + +#if CONFIG_LIBUKPRINT_LOGBUF + uk_print_logbuf_write(&msg); +#endif /* CONFIG_LIBUKPRINT_LOGBUF */ + +#if CONFIG_LIBUKCONSOLE + uk_print_console_write(&msg); +#endif /* CONFIG_LIBUKCONSOLE */ + + UK_PRINT_MSG_FREE(msg); +} + +void _uk_printk(int flags, __u16 libid, + const char *srcname __maybe_unused, + unsigned int srcline __maybe_unused, + const char *fmt, ...) +{ + struct uk_print_msg msg; + va_list ap; + + va_start(ap, fmt); + UK_PRINT_MSG_ALLOC(msg, flags, libid, srcname, srcline, fmt, ap); + +#if CONFIG_LIBUKPRINT_LOGBUF + uk_print_logbuf_write(&msg); +#endif /* CONFIG_LIBUKPRINT_LOGBUF */ + +#if CONFIG_LIBUKCONSOLE + uk_print_console_write(&msg); +#endif /* CONFIG_LIBUKCONSOLE */ + + UK_PRINT_MSG_FREE(msg); + va_end(ap); +} +#endif /* CONFIG_LIBUKPRINT_PRINTK */ diff --git a/lib/ukdebug/snprintf.c b/lib/ukprint/snprintf.c similarity index 73% rename from lib/ukdebug/snprintf.c rename to lib/ukprint/snprintf.c index 62addff07c..f0bf4dfea6 100644 --- a/lib/ukdebug/snprintf.c +++ b/lib/ukprint/snprintf.c @@ -1,55 +1,8 @@ /* SPDX-License-Identifier: BSD-3-Clause */ -/* - **************************************************************************** - * - * File: printf.c - * Author: Juergen Gross - * Simon Kuenzer - * - * Date: Jun 2016, Jan 2020 - * - * Environment: Unikraft - * Description: Internal low-weight snprintf function for ukdebug - * (FreeBSD port) - * - **************************************************************************** - */ - -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Copyright (c) 2011 The FreeBSD Foundation - * All rights reserved. - * Portions of this software were developed by David Chisnall - * under sponsorship from the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights reserved. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. */ #include @@ -65,6 +18,7 @@ #define MAXNBUF 65 static char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; + /* * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse * order; return an optional length and a pointer to the last character @@ -90,7 +44,7 @@ static inline char *ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, /* * Scaled down version of printf(3). */ -int __uk_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) +int uk_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) { #define PCHAR(c) \ { \ @@ -390,13 +344,13 @@ int __uk_vsnprintf(char *str, size_t size, const char *fmt, va_list ap) #undef PCHAR } -int __uk_snprintf(char *str, size_t size, const char *fmt, ...) +int uk_snprintf(char *str, size_t size, const char *fmt, ...) { int ret; va_list ap; va_start(ap, fmt); - ret = __uk_vsnprintf(str, size, fmt, ap); + ret = uk_vsnprintf(str, size, fmt, ap); va_end(ap); return ret; diff --git a/lib/ukprint/snprintf.h b/lib/ukprint/snprintf.h new file mode 100644 index 0000000000..10c8aac94c --- /dev/null +++ b/lib/ukprint/snprintf.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights reserved. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#ifndef __UK_PRINT_SNPRINTF_H__ +#define __UK_PRINT_SNPRINTF_H__ + +#include + +/* + * Point uk_(v)snprintf to library-internal implementation as soon as + * we do not use lib/nolibc as libc. + */ +#if CONFIG_LIBNOLIBC +#include + +#define uk_vsnprintf(...) vsnprintf(__VA_ARGS__) +#define uk_snprintf(...) snprintf(__VA_ARGS__) + +#else /* !CONFIG_LIBNOLIBC */ +#include +#include +#include + +int uk_vsnprintf(char *str, size_t size, const char *fmt, va_list ap); +int uk_snprintf(char *str, size_t size, const char *fmt, ...) __printf(3, 4); + +#endif /* !CONFIG_LIBNOLIBC */ + +#endif /* __UK_PRINT_SNPRINTF_H__ */ diff --git a/lib/ukprint/store.c b/lib/ukprint/store.c new file mode 100644 index 0000000000..eb7e3e6a3a --- /dev/null +++ b/lib/ukprint/store.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#include +#include +#include +#include + +extern unsigned int uk_print_console_lvl; + +static int uk_print_get_console_lvl(void *cookie __unused, __u8 *lvl) +{ + *lvl = uk_print_console_lvl; + return 0; +} + +static int uk_print_set_console_lvl(void *cookie __unused, __u8 lvl) +{ + uk_print_console_lvl = lvl; + return 0; +} + +UK_STORE_STATIC_ENTRY(UK_PRINT_KLVL_ENTRY_ID, + console_lvl, u8, + uk_print_get_console_lvl, + uk_print_set_console_lvl); diff --git a/lib/ukprint/uk_print_msg.h b/lib/ukprint/uk_print_msg.h new file mode 100644 index 0000000000..6b75feaf77 --- /dev/null +++ b/lib/ukprint/uk_print_msg.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: BSD-3-Clause */ +/* Copyright (c) 2024, Unikraft GmbH and The Unikraft Authors. + * Licensed under the BSD-3-Clause License (the "License"). + * You may not use this file except in compliance with the License. + */ + +#ifndef __UK_PRINT_MSG_H__ +#define __UK_PRINT_MSG_H__ + +#include +#include + +extern unsigned int uk_print_console_lvl; + +struct uk_print_msg { + int flags; + __u16 libid; +#if CONFIG_LIBUKPRINT_PRINT_SRCNAME + const char *srcname; + unsigned int srcline; +#endif /* CONFIG_LIBUKPRINT_PRINT_SRCNAME */ +#if CONFIG_LIBUKPRINT_PRINT_TIME + __nsec timestamp; +#endif /* CONFIG_LIBUKPRINT_PRINT_TIME */ +#if CONFIG_LIBUKPRINT_PRINT_THREAD + const char *threadname; /* may be NULL */ +#endif /* CONFIG_LIBUKPRINT_PRINT_THREAD */ +#if CONFIG_LIBUKPRINT_PRINT_CALLER + __uptr retaddr; + __uptr frameaddr; +#endif /* CONFIG_LIBUKPRINT_PRINT_CALLER */ + const char *fmt; + va_list ap; +#if CONFIG_LIBUKPRINT_LOGBUF + __sz len; + char msg[]; +#endif /* CONFIG_LIBUKPRINT_LOGBUF */ +}; + +#if CONFIG_LIBUKCONSOLE +void uk_print_console_write(struct uk_print_msg *msg); +#endif /* CONFIG_LIBUKCONSOLE */ + +#if CONFIG_LIBUKPRINT_LOGBUF +int uk_print_logbuf_write(struct uk_print_msg *msg); +#endif /* CONFIG_LIBUKPRINT_LOGBUF */ + +#endif /* __UK_PRINT_MSG_H__ */ diff --git a/lib/ukrust/ukrust_sys/bindings_helper.h b/lib/ukrust/ukrust_sys/bindings_helper.h index 4161aa270b..99c78e3780 100644 --- a/lib/ukrust/ukrust_sys/bindings_helper.h +++ b/lib/ukrust/ukrust_sys/bindings_helper.h @@ -42,7 +42,7 @@ #if CONFIG_LIBUKDEBUG #include -#include +#include #include #include #endif diff --git a/lib/ukstreambuf/tests/test_ukstreambuf.c b/lib/ukstreambuf/tests/test_ukstreambuf.c index dda2f24e02..05afce8d8a 100644 --- a/lib/ukstreambuf/tests/test_ukstreambuf.c +++ b/lib/ukstreambuf/tests/test_ukstreambuf.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include UK_TESTCASE(ukstreambuf, streambuf_init) { diff --git a/lib/uktest/include/uk/test.h b/lib/uktest/include/uk/test.h index 701b2f21d9..242a28581c 100644 --- a/lib/uktest/include/uk/test.h +++ b/lib/uktest/include/uk/test.h @@ -200,7 +200,7 @@ /* Custom print method. */ #define uk_test_printf(fmt, ...) \ - _uk_printk(KLVL_INFO, UKLIBID_NONE, __NULL, 0x0, \ + _uk_printk(UK_PRINT_KLVL_NONE, UKLIBID_NONE, __NULL, 0x0, \ "\t" fmt, ##__VA_ARGS__) diff --git a/lib/uktest/test.c b/lib/uktest/test.c index 9fbc347bb7..8d029ea260 100644 --- a/lib/uktest/test.c +++ b/lib/uktest/test.c @@ -178,14 +178,15 @@ uk_testsuite_run(struct uk_testsuite *suite) #endif /* CONFIG_LIBUKTEST_LOG_STATS */ #ifdef CONFIG_LIBUKTEST_LOG_TESTS - _uk_printk(KLVL_INFO, UKLIBID_NONE, __NULL, 0x0, + _uk_printk(UK_PRINT_KLVL_NONE, UKLIBID_NONE, __NULL, 0x0, (LVLC_TESTNAME "test:" UK_ANSI_MOD_RESET " %s->%s"), suite->name, esac->name); if (esac->desc != NULL) - _uk_printk(KLVL_INFO, UKLIBID_NONE, __NULL, 0x0, - ": %s\n", esac->desc); + _uk_printk(UK_PRINT_KLVL_NONE, UKLIBID_NONE, __NULL, + 0x0, ": %s\n", esac->desc); else - _uk_printk(KLVL_INFO, UKLIBID_NONE, __NULL, 0x0, "\n"); + _uk_printk(UK_PRINT_KLVL_NONE, UKLIBID_NONE, __NULL, + 0x0, "\n"); #endif /* CONFIG_LIBUKTEST_LOG_TESTS */ esac->func(esac); diff --git a/lib/ukvmem/tests/test_vmem.c b/lib/ukvmem/tests/test_vmem.c index 5fdb81b8c4..d7f761dec1 100644 --- a/lib/ukvmem/tests/test_vmem.c +++ b/lib/ukvmem/tests/test_vmem.c @@ -32,7 +32,7 @@ #define PROT_RWX PAGE_ATTR_PROT_RWX #define pr_info(fmt, ...) \ - _uk_printk(KLVL_INFO, __NULL, __NULL, 0x0, fmt, ##__VA_ARGS__) + _uk_printk(UK_PRINT_KLVL_INFO, __NULL, __NULL, 0x0, fmt, ##__VA_ARGS__) #define vmem_bug_on(cond) \ do { \ diff --git a/plat/common/x86/traps.c b/plat/common/x86/traps.c index 33a29a4527..efe36ba32d 100644 --- a/plat/common/x86/traps.c +++ b/plat/common/x86/traps.c @@ -37,7 +37,6 @@ #include #include #include -#include /* A general word of caution when writing trap handlers. The platform trap * entry code is set up to properly save general-purpose registers (e.g., rsi, @@ -86,7 +85,6 @@ void do_unhandled_trap(int trapnr, char *str, struct __regs *regs, uk_pr_info("Regs address %p\n", regs); /* TODO revisit when UK_CRASH will also dump the registers */ dump_regs(regs); - uk_asmdumpk(KLVL_CRIT, (void *) regs->rip, 8); UK_CRASH("Crashing\n"); } @@ -106,7 +104,6 @@ void do_page_fault(struct __regs *regs, unsigned long error_code) #if !__OMIT_FRAMEPOINTER__ stack_walk_for_frame(regs->rbp); #endif /* !__OMIT_FRAMEPOINTER__ */ - uk_asmdumpk(KLVL_CRIT, (void *) regs->rip, 6); dump_mem(regs->rsp); dump_mem(regs->rbp); dump_mem(regs->rip);