aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Jones <michaelrj@google.com>2024-06-07 11:37:12 -0700
committerGitHub <noreply@github.com>2024-06-07 11:37:12 -0700
commit11d643f0b11c041d7030d43a328adf2eb3ba4e3d (patch)
tree749305ac61d614d1b3f2b15ba5736a8b67b5c9e2
parent2c047e67a5bfb479d7422f5b270e7f90ae037508 (diff)
downloadllvm-11d643f0b11c041d7030d43a328adf2eb3ba4e3d.zip
llvm-11d643f0b11c041d7030d43a328adf2eb3ba4e3d.tar.gz
llvm-11d643f0b11c041d7030d43a328adf2eb3ba4e3d.tar.bz2
[libc] Add baremetal printf (#94078)
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).
-rw-r--r--libc/src/stdio/CMakeLists.txt35
-rw-r--r--libc/src/stdio/baremetal/CMakeLists.txt12
-rw-r--r--libc/src/stdio/baremetal/printf.cpp57
-rw-r--r--libc/src/stdio/generic/CMakeLists.txt33
-rw-r--r--libc/src/stdio/generic/printf.cpp (renamed from libc/src/stdio/printf.cpp)0
-rw-r--r--libc/src/stdio/generic/vprintf.cpp (renamed from libc/src/stdio/vprintf.cpp)0
6 files changed, 104 insertions, 33 deletions
diff --git a/libc/src/stdio/CMakeLists.txt b/libc/src/stdio/CMakeLists.txt
index 1056f38..ee48e44 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
@@ -216,16 +193,6 @@ add_entrypoint_object(
)
add_entrypoint_object(
- vprintf
- SRCS
- vprintf.cpp
- HDRS
- vprintf.h
- DEPENDS
- ${printf_deps}
-)
-
-add_entrypoint_object(
vfprintf
SRCS
vfprintf.cpp
@@ -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 6508927..a1a5ba5 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 0000000..597078b
--- /dev/null
+++ b/libc/src/stdio/baremetal/printf.cpp
@@ -0,0 +1,57 @@
+//===-- 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 <stdarg.h>
+
+// 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 {
+
+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;
+}
+
+} // namespace
+
+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 ae25591..9cd4cfd 100644
--- a/libc/src/stdio/generic/CMakeLists.txt
+++ b/libc/src/stdio/generic/CMakeLists.txt
@@ -363,6 +363,39 @@ 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}
+)
+
add_entrypoint_object(
fgets
SRCS
diff --git a/libc/src/stdio/printf.cpp b/libc/src/stdio/generic/printf.cpp
index 5701ca9..5701ca9 100644
--- a/libc/src/stdio/printf.cpp
+++ b/libc/src/stdio/generic/printf.cpp
diff --git a/libc/src/stdio/vprintf.cpp b/libc/src/stdio/generic/vprintf.cpp
index eff968d..eff968d 100644
--- a/libc/src/stdio/vprintf.cpp
+++ b/libc/src/stdio/generic/vprintf.cpp