From 4d082a23fb8964a433d5ae95a3b65af54a953716 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Fri, 31 May 2024 15:51:57 -0700 Subject: [PATCH 1/3] [libc] Add baremetal printf For baremetal targets that don't support FILE, this version of printf just writes directly to a function provided by a vendor. To do this both printf and vprintf were moved to /generic (vprintf since they need the same flags and cmake gets funky about setting variables in one file and reading them in another). --- libc/src/stdio/CMakeLists.txt | 35 +--------------- libc/src/stdio/baremetal/CMakeLists.txt | 12 ++++++ libc/src/stdio/baremetal/printf.cpp | 51 ++++++++++++++++++++++++ libc/src/stdio/generic/CMakeLists.txt | 35 ++++++++++++++++ libc/src/stdio/{ => generic}/printf.cpp | 0 libc/src/stdio/{ => generic}/vprintf.cpp | 0 6 files changed, 100 insertions(+), 33 deletions(-) create mode 100644 libc/src/stdio/baremetal/printf.cpp rename libc/src/stdio/{ => generic}/printf.cpp (100%) rename libc/src/stdio/{ => generic}/vprintf.cpp (100%) diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt index 1056f38fc7513..ee48e441d1c59 100644 --- a/libc/src/stdio/CMakeLists.txt +++ b/libc/src/stdio/CMakeLists.txt @@ -159,29 +159,6 @@ add_entrypoint_object( libc.src.stdio.printf_core.writer ) -list(APPEND printf_deps - libc.src.__support.arg_list - libc.src.stdio.printf_core.vfprintf_internal -) - -if(LLVM_LIBC_FULL_BUILD) - list(APPEND printf_deps - libc.src.__support.File.file - libc.src.__support.File.platform_file - libc.src.__support.File.platform_stdout - ) -endif() - -add_entrypoint_object( - printf - SRCS - printf.cpp - HDRS - printf.h - DEPENDS - ${printf_deps} -) - add_entrypoint_object( fprintf SRCS @@ -215,16 +192,6 @@ add_entrypoint_object( libc.src.stdio.printf_core.writer ) -add_entrypoint_object( - vprintf - SRCS - vprintf.cpp - HDRS - vprintf.h - DEPENDS - ${printf_deps} -) - add_entrypoint_object( vfprintf SRCS @@ -286,6 +253,7 @@ add_stdio_entrypoint_object(fwrite) add_stdio_entrypoint_object(fputc) add_stdio_entrypoint_object(putc) add_stdio_entrypoint_object(putchar) +add_stdio_entrypoint_object(printf) add_stdio_entrypoint_object(fgetc) add_stdio_entrypoint_object(fgetc_unlocked) add_stdio_entrypoint_object(getc) @@ -297,3 +265,4 @@ add_stdio_entrypoint_object(ungetc) add_stdio_entrypoint_object(stdin) add_stdio_entrypoint_object(stdout) add_stdio_entrypoint_object(stderr) +add_stdio_entrypoint_object(vprintf) diff --git a/libc/src/stdio/baremetal/CMakeLists.txt b/libc/src/stdio/baremetal/CMakeLists.txt index 65089274050bd..a1a5ba5faaf3d 100644 --- a/libc/src/stdio/baremetal/CMakeLists.txt +++ b/libc/src/stdio/baremetal/CMakeLists.txt @@ -7,3 +7,15 @@ add_entrypoint_object( DEPENDS libc.include.stdio ) + +add_entrypoint_object( + printf + SRCS + printf.cpp + HDRS + ../printf.h + DEPENDS + libc.src.stdio.printf_core.printf_main + libc.src.stdio.printf_core.writer + libc.src.__support.arg_list +) diff --git a/libc/src/stdio/baremetal/printf.cpp b/libc/src/stdio/baremetal/printf.cpp new file mode 100644 index 0000000000000..f14f2c1afb790 --- /dev/null +++ b/libc/src/stdio/baremetal/printf.cpp @@ -0,0 +1,51 @@ +//===-- Implementation of printf for baremetal ------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "src/stdio/printf.h" +#include "src/__support/arg_list.h" +#include "src/stdio/printf_core/core_structs.h" +#include "src/stdio/printf_core/printf_main.h" +#include "src/stdio/printf_core/writer.h" + +#include + +// This is intended to be provided by the vendor. Name TBD +extern "C" size_t __llvm_libc_raw_write(const char *s, size_t size); + +namespace LIBC_NAMESPACE { + +LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { + size_t written = __llvm_libc_raw_write(new_str.data(), new_str.size()); + if (written != new_str.size()) + return printf_core::FILE_WRITE_ERROR; + return printf_core::WRITE_OK; +} + +LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { + va_list vlist; + va_start(vlist, format); + internal::ArgList args(vlist); // This holder class allows for easier copying + // and pointer semantics, as well as handling + // destruction automatically. + va_end(vlist); + constexpr size_t BUFF_SIZE = 1024; + char buffer[BUFF_SIZE]; + + printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr); + printf_core::Writer writer(&wb); + + int retval = printf_core::printf_main(&writer, format, args); + + int flushval = wb.overflow_write(""); + if (flushval != printf_core::WRITE_OK) + retval = flushval; + + return retval; +} + +} // namespace LIBC_NAMESPACE diff --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt index ae255917adfe3..65f052b841958 100644 --- a/libc/src/stdio/generic/CMakeLists.txt +++ b/libc/src/stdio/generic/CMakeLists.txt @@ -363,6 +363,41 @@ add_entrypoint_object( libc.src.__support.File.platform_file ) +list(APPEND printf_deps + libc.src.__support.arg_list + libc.src.stdio.printf_core.vfprintf_internal +) + +if(LLVM_LIBC_FULL_BUILD) + list(APPEND printf_deps + libc.src.__support.File.file + libc.src.__support.File.platform_file + libc.src.__support.File.platform_stdout + ) +endif() + +add_entrypoint_object( + printf + SRCS + printf.cpp + HDRS + ../printf.h + DEPENDS + ${printf_deps} +) + +add_entrypoint_object( + vprintf + SRCS + vprintf.cpp + HDRS + ../vprintf.h + DEPENDS + ${printf_deps} +) + +message(STATUS "the printf deps are ${printf_deps}") + add_entrypoint_object( fgets SRCS diff --git a/libc/src/stdio/printf.cpp b/libc/src/stdio/generic/printf.cpp similarity index 100% rename from libc/src/stdio/printf.cpp rename to libc/src/stdio/generic/printf.cpp diff --git a/libc/src/stdio/vprintf.cpp b/libc/src/stdio/generic/vprintf.cpp similarity index 100% rename from libc/src/stdio/vprintf.cpp rename to libc/src/stdio/generic/vprintf.cpp From d3cc1f7dadfd8e5e4653aaec50e51bd50f7c7130 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Tue, 4 Jun 2024 15:51:01 -0700 Subject: [PATCH 2/3] address comments --- libc/src/stdio/baremetal/printf.cpp | 4 ++++ libc/src/stdio/generic/CMakeLists.txt | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libc/src/stdio/baremetal/printf.cpp b/libc/src/stdio/baremetal/printf.cpp index f14f2c1afb790..886aea618c8b9 100644 --- a/libc/src/stdio/baremetal/printf.cpp +++ b/libc/src/stdio/baremetal/printf.cpp @@ -19,6 +19,8 @@ extern "C" size_t __llvm_libc_raw_write(const char *s, size_t size); namespace LIBC_NAMESPACE { +namespace { + LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { size_t written = __llvm_libc_raw_write(new_str.data(), new_str.size()); if (written != new_str.size()) @@ -26,6 +28,8 @@ LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) { return printf_core::WRITE_OK; } +} // namespace + LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) { va_list vlist; va_start(vlist, format); diff --git a/libc/src/stdio/generic/CMakeLists.txt b/libc/src/stdio/generic/CMakeLists.txt index 65f052b841958..9cd4cfdae17f4 100644 --- a/libc/src/stdio/generic/CMakeLists.txt +++ b/libc/src/stdio/generic/CMakeLists.txt @@ -396,8 +396,6 @@ add_entrypoint_object( ${printf_deps} ) -message(STATUS "the printf deps are ${printf_deps}") - add_entrypoint_object( fgets SRCS From 93fe01482f5e66a84be300cd4d40bc078b5a9cbe Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Thu, 6 Jun 2024 14:00:40 -0700 Subject: [PATCH 3/3] adjust comments --- libc/src/stdio/baremetal/printf.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libc/src/stdio/baremetal/printf.cpp b/libc/src/stdio/baremetal/printf.cpp index 886aea618c8b9..597078b1ede51 100644 --- a/libc/src/stdio/baremetal/printf.cpp +++ b/libc/src/stdio/baremetal/printf.cpp @@ -14,7 +14,9 @@ #include -// This is intended to be provided by the vendor. Name TBD +// TODO(https://github.com/llvm/llvm-project/issues/94685) unify baremetal hooks + +// This is intended to be provided by the vendor. extern "C" size_t __llvm_libc_raw_write(const char *s, size_t size); namespace LIBC_NAMESPACE {