Skip to content

Commit 11d643f

Browse files
[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).
1 parent 2c047e6 commit 11d643f

File tree

6 files changed

+104
-33
lines changed

6 files changed

+104
-33
lines changed

libc/src/stdio/CMakeLists.txt

+2-33
Original file line numberDiff line numberDiff line change
@@ -159,29 +159,6 @@ add_entrypoint_object(
159159
libc.src.stdio.printf_core.writer
160160
)
161161

162-
list(APPEND printf_deps
163-
libc.src.__support.arg_list
164-
libc.src.stdio.printf_core.vfprintf_internal
165-
)
166-
167-
if(LLVM_LIBC_FULL_BUILD)
168-
list(APPEND printf_deps
169-
libc.src.__support.File.file
170-
libc.src.__support.File.platform_file
171-
libc.src.__support.File.platform_stdout
172-
)
173-
endif()
174-
175-
add_entrypoint_object(
176-
printf
177-
SRCS
178-
printf.cpp
179-
HDRS
180-
printf.h
181-
DEPENDS
182-
${printf_deps}
183-
)
184-
185162
add_entrypoint_object(
186163
fprintf
187164
SRCS
@@ -215,16 +192,6 @@ add_entrypoint_object(
215192
libc.src.stdio.printf_core.writer
216193
)
217194

218-
add_entrypoint_object(
219-
vprintf
220-
SRCS
221-
vprintf.cpp
222-
HDRS
223-
vprintf.h
224-
DEPENDS
225-
${printf_deps}
226-
)
227-
228195
add_entrypoint_object(
229196
vfprintf
230197
SRCS
@@ -286,6 +253,7 @@ add_stdio_entrypoint_object(fwrite)
286253
add_stdio_entrypoint_object(fputc)
287254
add_stdio_entrypoint_object(putc)
288255
add_stdio_entrypoint_object(putchar)
256+
add_stdio_entrypoint_object(printf)
289257
add_stdio_entrypoint_object(fgetc)
290258
add_stdio_entrypoint_object(fgetc_unlocked)
291259
add_stdio_entrypoint_object(getc)
@@ -297,3 +265,4 @@ add_stdio_entrypoint_object(ungetc)
297265
add_stdio_entrypoint_object(stdin)
298266
add_stdio_entrypoint_object(stdout)
299267
add_stdio_entrypoint_object(stderr)
268+
add_stdio_entrypoint_object(vprintf)

libc/src/stdio/baremetal/CMakeLists.txt

+12
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,15 @@ add_entrypoint_object(
77
DEPENDS
88
libc.include.stdio
99
)
10+
11+
add_entrypoint_object(
12+
printf
13+
SRCS
14+
printf.cpp
15+
HDRS
16+
../printf.h
17+
DEPENDS
18+
libc.src.stdio.printf_core.printf_main
19+
libc.src.stdio.printf_core.writer
20+
libc.src.__support.arg_list
21+
)

libc/src/stdio/baremetal/printf.cpp

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
//===-- Implementation of printf for baremetal ------------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "src/stdio/printf.h"
10+
#include "src/__support/arg_list.h"
11+
#include "src/stdio/printf_core/core_structs.h"
12+
#include "src/stdio/printf_core/printf_main.h"
13+
#include "src/stdio/printf_core/writer.h"
14+
15+
#include <stdarg.h>
16+
17+
// TODO(https://github.com/llvm/llvm-project/issues/94685) unify baremetal hooks
18+
19+
// This is intended to be provided by the vendor.
20+
extern "C" size_t __llvm_libc_raw_write(const char *s, size_t size);
21+
22+
namespace LIBC_NAMESPACE {
23+
24+
namespace {
25+
26+
LIBC_INLINE int raw_write_hook(cpp::string_view new_str, void *) {
27+
size_t written = __llvm_libc_raw_write(new_str.data(), new_str.size());
28+
if (written != new_str.size())
29+
return printf_core::FILE_WRITE_ERROR;
30+
return printf_core::WRITE_OK;
31+
}
32+
33+
} // namespace
34+
35+
LLVM_LIBC_FUNCTION(int, printf, (const char *__restrict format, ...)) {
36+
va_list vlist;
37+
va_start(vlist, format);
38+
internal::ArgList args(vlist); // This holder class allows for easier copying
39+
// and pointer semantics, as well as handling
40+
// destruction automatically.
41+
va_end(vlist);
42+
constexpr size_t BUFF_SIZE = 1024;
43+
char buffer[BUFF_SIZE];
44+
45+
printf_core::WriteBuffer wb(buffer, BUFF_SIZE, &raw_write_hook, nullptr);
46+
printf_core::Writer writer(&wb);
47+
48+
int retval = printf_core::printf_main(&writer, format, args);
49+
50+
int flushval = wb.overflow_write("");
51+
if (flushval != printf_core::WRITE_OK)
52+
retval = flushval;
53+
54+
return retval;
55+
}
56+
57+
} // namespace LIBC_NAMESPACE

libc/src/stdio/generic/CMakeLists.txt

+33
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,39 @@ add_entrypoint_object(
363363
libc.src.__support.File.platform_file
364364
)
365365

366+
list(APPEND printf_deps
367+
libc.src.__support.arg_list
368+
libc.src.stdio.printf_core.vfprintf_internal
369+
)
370+
371+
if(LLVM_LIBC_FULL_BUILD)
372+
list(APPEND printf_deps
373+
libc.src.__support.File.file
374+
libc.src.__support.File.platform_file
375+
libc.src.__support.File.platform_stdout
376+
)
377+
endif()
378+
379+
add_entrypoint_object(
380+
printf
381+
SRCS
382+
printf.cpp
383+
HDRS
384+
../printf.h
385+
DEPENDS
386+
${printf_deps}
387+
)
388+
389+
add_entrypoint_object(
390+
vprintf
391+
SRCS
392+
vprintf.cpp
393+
HDRS
394+
../vprintf.h
395+
DEPENDS
396+
${printf_deps}
397+
)
398+
366399
add_entrypoint_object(
367400
fgets
368401
SRCS
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)