Skip to content

Commit b8dfdd0

Browse files
committed
[libc] Support opaque FILE* on baremetal
This change expands the stdio support on baremetal to support opaque FILE*. This builds on top of the existing baremetal embedding API; we treat the standard FILE* streams as pointers that point to the cookie symbols which are a part of the embedding API. This also allows users to define their own FILE* streams, but we don't (yet) support the API that return FILE* such as fopen or fopencookie.
1 parent dbf4525 commit b8dfdd0

File tree

23 files changed

+530
-160
lines changed

23 files changed

+530
-160
lines changed

clang/cmake/caches/Fuchsia-stage2.cmake

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv7em-none-eabi;armv8m.main-n
341341
foreach(lang C;CXX;ASM)
342342
# TODO: The preprocessor defines workaround various issues in libc and libc++ integration.
343343
# These should be addressed and removed over time.
344-
set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dfputs(string, stream)=puts(string)\" -D_LIBCPP_PRINT=1")
344+
set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "--target=${target} -Wno-atomic-alignment")
345345
if(NOT ${target} STREQUAL "aarch64-none-elf")
346346
set(RUNTIMES_${target}_CMAKE_${lang}_local_flags "${RUNTIMES_${target}_CMAKE_${lang}_local_flags} -mthumb")
347347
endif()
@@ -372,6 +372,7 @@ foreach(target armv6m-none-eabi;armv7m-none-eabi;armv7em-none-eabi;armv8m.main-n
372372
set(RUNTIMES_${target}_LIBCXX_ENABLE_RTTI OFF CACHE BOOL "")
373373
set(RUNTIMES_${target}_LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
374374
set(RUNTIMES_${target}_LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
375+
set(RUNTIMES_${target}_LIBCXX_HAS_TERMINAL_AVAILABLE OFF CACHE BOOL "")
375376
set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
376377
set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
377378
set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "")
@@ -406,7 +407,7 @@ foreach(target riscv32-unknown-elf)
406407
foreach(lang C;CXX;ASM)
407408
# TODO: The preprocessor defines workaround various issues in libc and libc++ integration.
408409
# These should be addressed and removed over time.
409-
set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -march=rv32imafc -mabi=ilp32f -Wno-atomic-alignment \"-Dvfprintf(stream, format, vlist)=vprintf(format, vlist)\" \"-Dfprintf(stream, format, ...)=printf(format)\" \"-Dfputs(string, stream)=puts(string)\" -D_LIBCPP_PRINT=1" CACHE STRING "")
410+
set(RUNTIMES_${target}_CMAKE_${lang}_FLAGS "--target=${target} -march=rv32imafc -mabi=ilp32f -Wno-atomic-alignment" CACHE STRING "")
410411
endforeach()
411412
foreach(type SHARED;MODULE;EXE)
412413
set(RUNTIMES_${target}_CMAKE_${type}_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")
@@ -427,6 +428,7 @@ foreach(target riscv32-unknown-elf)
427428
set(RUNTIMES_${target}_LIBCXX_ENABLE_RTTI OFF CACHE BOOL "")
428429
set(RUNTIMES_${target}_LIBCXX_ENABLE_THREADS OFF CACHE BOOL "")
429430
set(RUNTIMES_${target}_LIBCXX_ENABLE_MONOTONIC_CLOCK OFF CACHE BOOL "")
431+
set(RUNTIMES_${target}_LIBCXX_HAS_TERMINAL_AVAILABLE OFF CACHE BOOL "")
430432
set(RUNTIMES_${target}_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
431433
set(RUNTIMES_${target}_LLVM_INCLUDE_TESTS OFF CACHE BOOL "")
432434
set(RUNTIMES_${target}_LLVM_ENABLE_ASSERTIONS OFF CACHE BOOL "")

libc/config/baremetal/aarch64/entrypoints.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS
124124

125125
# stdio.h entrypoints
126126
libc.src.stdio.asprintf
127+
libc.src.stdio.feof
128+
libc.src.stdio.ferror
129+
libc.src.stdio.fprintf
130+
libc.src.stdio.fputc
131+
libc.src.stdio.fputs
132+
libc.src.stdio.fwrite
127133
libc.src.stdio.getchar
128134
libc.src.stdio.printf
135+
libc.src.stdio.putc
129136
libc.src.stdio.putchar
130137
libc.src.stdio.puts
131138
libc.src.stdio.remove
@@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS
134141
libc.src.stdio.sprintf
135142
libc.src.stdio.sscanf
136143
libc.src.stdio.vasprintf
144+
libc.src.stdio.vfprintf
137145
libc.src.stdio.vprintf
138146
libc.src.stdio.vscanf
139147
libc.src.stdio.vsnprintf

libc/config/baremetal/arm/entrypoints.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS
124124

125125
# stdio.h entrypoints
126126
libc.src.stdio.asprintf
127+
libc.src.stdio.feof
128+
libc.src.stdio.ferror
129+
libc.src.stdio.fprintf
130+
libc.src.stdio.fputc
131+
libc.src.stdio.fputs
132+
libc.src.stdio.fwrite
127133
libc.src.stdio.getchar
128134
libc.src.stdio.printf
135+
libc.src.stdio.putc
129136
libc.src.stdio.putchar
130137
libc.src.stdio.puts
131138
libc.src.stdio.remove
@@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS
134141
libc.src.stdio.sprintf
135142
libc.src.stdio.sscanf
136143
libc.src.stdio.vasprintf
144+
libc.src.stdio.vfprintf
137145
libc.src.stdio.vprintf
138146
libc.src.stdio.vscanf
139147
libc.src.stdio.vsnprintf

libc/config/baremetal/riscv/entrypoints.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,15 @@ set(TARGET_LIBC_ENTRYPOINTS
124124

125125
# stdio.h entrypoints
126126
libc.src.stdio.asprintf
127+
libc.src.stdio.feof
128+
libc.src.stdio.ferror
129+
libc.src.stdio.fprintf
130+
libc.src.stdio.fputc
131+
libc.src.stdio.fputs
132+
libc.src.stdio.fwrite
127133
libc.src.stdio.getchar
128134
libc.src.stdio.printf
135+
libc.src.stdio.putc
129136
libc.src.stdio.putchar
130137
libc.src.stdio.puts
131138
libc.src.stdio.remove
@@ -134,6 +141,7 @@ set(TARGET_LIBC_ENTRYPOINTS
134141
libc.src.stdio.sprintf
135142
libc.src.stdio.sscanf
136143
libc.src.stdio.vasprintf
144+
libc.src.stdio.vfprintf
137145
libc.src.stdio.vprintf
138146
libc.src.stdio.vscanf
139147
libc.src.stdio.vsnprintf

libc/src/__support/OSUtil/baremetal/io.cpp

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -8,49 +8,15 @@
88

99
#include "io.h"
1010

11+
#include "hdr/types/FILE.h"
1112
#include "src/__support/CPP/string_view.h"
1213
#include "src/__support/macros/config.h"
1314

1415
namespace LIBC_NAMESPACE_DECL {
1516

16-
// These are intended to be provided by the vendor.
17-
//
18-
// The signature of these types and functions intentionally match `fopencookie`
19-
// which allows the following:
20-
//
21-
// ```
22-
// struct __llvm_libc_stdio_cookie { ... };
23-
// ...
24-
// struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
25-
// cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read };
26-
// FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func);
27-
// ...
28-
// struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
29-
// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write };
30-
// FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func);
31-
// ...
32-
// struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
33-
// cookie_io_functions_t stderr_func = { .write = __llvm_libc_stdio_write };
34-
// FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func);
35-
// ```
36-
//
37-
// At the same time, implementation of functions like `printf` and `scanf` can
38-
// use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid
39-
// the extra indirection.
40-
//
41-
// All three symbols `__llvm_libc_stdin_cookie`, `__llvm_libc_stdout_cookie`,
42-
// and `__llvm_libc_stderr_cookie` must be provided, even if they don't point
43-
// at anything.
44-
45-
struct __llvm_libc_stdio_cookie;
46-
47-
extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
48-
extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
49-
extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
50-
51-
extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size);
52-
extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf,
53-
size_t size);
17+
extern "C" FILE *stdin = reinterpret_cast<FILE *>(&__llvm_libc_stdin_cookie);
18+
extern "C" FILE *stdout = reinterpret_cast<FILE *>(&__llvm_libc_stdout_cookie);
19+
extern "C" FILE *stderr = reinterpret_cast<FILE *>(&__llvm_libc_stderr_cookie);
5420

5521
ssize_t read_from_stdin(char *buf, size_t size) {
5622
return __llvm_libc_stdio_read(static_cast<void *>(&__llvm_libc_stdin_cookie),

libc/src/__support/OSUtil/baremetal/io.h

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,45 @@
1616

1717
namespace LIBC_NAMESPACE_DECL {
1818

19+
// These are intended to be provided by the vendor.
20+
//
21+
// The signature of these types and functions intentionally match `fopencookie`
22+
// which allows the following:
23+
//
24+
// ```
25+
// struct __llvm_libc_stdio_cookie { ... };
26+
// ...
27+
// struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
28+
// cookie_io_functions_t stdin_func = { .read = __llvm_libc_stdio_read };
29+
// FILE *stdin = fopencookie(&__llvm_libc_stdin_cookie, "r", stdin_func);
30+
// ...
31+
// struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
32+
// cookie_io_functions_t stdout_func = { .write = __llvm_libc_stdio_write };
33+
// FILE *stdout = fopencookie(&__llvm_libc_stdout_cookie, "w", stdout_func);
34+
// ...
35+
// struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
36+
// cookie_io_functions_t stderr_func = { .write = __llvm_libc_stdio_write };
37+
// FILE *stderr = fopencookie(&__llvm_libc_stderr_cookie, "w", stderr_func);
38+
// ```
39+
//
40+
// At the same time, implementation of functions like `printf` and `scanf` can
41+
// use `__llvm_libc_stdio_read` and `__llvm_libc_stdio_write` directly to avoid
42+
// the extra indirection.
43+
//
44+
// All three symbols `__llvm_libc_stdin_cookie`, `__llvm_libc_stdout_cookie`,
45+
// and `__llvm_libc_stderr_cookie` must be provided, even if they don't point
46+
// at anything.
47+
48+
struct __llvm_libc_stdio_cookie;
49+
50+
extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdin_cookie;
51+
extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stdout_cookie;
52+
extern "C" struct __llvm_libc_stdio_cookie __llvm_libc_stderr_cookie;
53+
54+
extern "C" ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size);
55+
extern "C" ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf,
56+
size_t size);
57+
1958
ssize_t read_from_stdin(char *buf, size_t size);
2059
void write_to_stderr(cpp::string_view msg);
2160
void write_to_stdout(cpp::string_view msg);

libc/src/stdio/baremetal/CMakeLists.txt

Lines changed: 133 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,111 @@
1+
add_header_library(
2+
fputc_internal
3+
HDRS
4+
fputc_internal.h
5+
DEPENDS
6+
libc.hdr.types.FILE
7+
libc.src.__support.CPP.string_view
8+
libc.src.__support.OSUtil.osutil
9+
)
10+
11+
add_header_library(
12+
fputs_internal
13+
HDRS
14+
fputs_internal.h
15+
DEPENDS
16+
libc.hdr.types.FILE
17+
libc.src.__support.CPP.string_view
18+
libc.src.__support.OSUtil.osutil
19+
)
20+
21+
add_header_library(
22+
fwrite_internal
23+
HDRS
24+
fwrite_internal.h
25+
DEPENDS
26+
libc.hdr.types.FILE
27+
libc.src.__support.OSUtil.osutil
28+
)
29+
30+
add_header_library(
31+
vfprintf_internal
32+
HDRS
33+
vfprintf_internal.h
34+
DEPENDS
35+
libc.hdr.types.FILE
36+
libc.hdr.stdio_macros
37+
libc.src.__support.arg_list
38+
libc.src.__support.CPP.limits
39+
libc.src.__support.CPP.string_view
40+
libc.src.__support.libc_errno
41+
libc.src.__support.OSUtil.osutil
42+
libc.src.stdio.printf_core.printf_main
43+
libc.src.stdio.printf_core.writer
44+
libc.src.stdio.printf_core.error_mapper
45+
libc.src.stdio.printf_core.core_structs
46+
)
47+
48+
add_entrypoint_object(
49+
feof
50+
SRCS
51+
feof.cpp
52+
HDRS
53+
../feof.h
54+
DEPENDS
55+
libc.hdr.types.FILE
56+
)
57+
58+
add_entrypoint_object(
59+
ferror
60+
SRCS
61+
ferror.cpp
62+
HDRS
63+
../ferror.h
64+
DEPENDS
65+
libc.hdr.types.FILE
66+
)
67+
68+
add_entrypoint_object(
69+
fprintf
70+
SRCS
71+
fprintf.cpp
72+
HDRS
73+
../fprintf.h
74+
DEPENDS
75+
.vfprintf_internal
76+
libc.src.__support.arg_list
77+
)
78+
79+
add_entrypoint_object(
80+
fputc
81+
SRCS
82+
fputc.cpp
83+
HDRS
84+
../fputc.h
85+
DEPENDS
86+
.fputc_internal
87+
)
88+
89+
add_entrypoint_object(
90+
fputs
91+
SRCS
92+
fputs.cpp
93+
HDRS
94+
../fputc.h
95+
DEPENDS
96+
.fputs_internal
97+
)
98+
99+
add_entrypoint_object(
100+
fwrite
101+
SRCS
102+
fwrite.cpp
103+
HDRS
104+
../fwrite.h
105+
DEPENDS
106+
.fwrite_internal
107+
)
108+
1109
add_entrypoint_object(
2110
getchar
3111
SRCS
@@ -27,14 +135,8 @@ add_entrypoint_object(
27135
HDRS
28136
../printf.h
29137
DEPENDS
30-
libc.src.stdio.printf_core.printf_main
31-
libc.src.stdio.printf_core.writer
32-
libc.src.stdio.printf_core.error_mapper
33-
libc.src.stdio.printf_core.core_structs
138+
.vfprintf_internal
34139
libc.src.__support.arg_list
35-
libc.src.__support.OSUtil.osutil
36-
libc.src.__support.libc_errno
37-
libc.src.__support.CPP.limits
38140
)
39141

40142
add_entrypoint_object(
@@ -44,8 +146,17 @@ add_entrypoint_object(
44146
HDRS
45147
../putchar.h
46148
DEPENDS
47-
libc.src.__support.OSUtil.osutil
48-
libc.src.__support.CPP.string_view
149+
.fputc_internal
150+
)
151+
152+
add_entrypoint_object(
153+
putc
154+
SRCS
155+
putc.cpp
156+
HDRS
157+
../putc.h
158+
DEPENDS
159+
.fputc_internal
49160
)
50161

51162
add_entrypoint_object(
@@ -55,8 +166,7 @@ add_entrypoint_object(
55166
HDRS
56167
../puts.h
57168
DEPENDS
58-
libc.src.__support.OSUtil.osutil
59-
libc.src.__support.CPP.string_view
169+
.fputs_internal
60170
)
61171

62172
add_header_library(
@@ -82,21 +192,26 @@ add_entrypoint_object(
82192
libc.src.__support.OSUtil.osutil
83193
)
84194

195+
add_entrypoint_object(
196+
vfprintf
197+
SRCS
198+
vfprintf.cpp
199+
HDRS
200+
../vfprintf.h
201+
DEPENDS
202+
.vfprintf_internal
203+
libc.src.__support.arg_list
204+
)
205+
85206
add_entrypoint_object(
86207
vprintf
87208
SRCS
88209
vprintf.cpp
89210
HDRS
90211
../vprintf.h
91212
DEPENDS
92-
libc.src.stdio.printf_core.printf_main
93-
libc.src.stdio.printf_core.writer
94-
libc.src.stdio.printf_core.error_mapper
95-
libc.src.stdio.printf_core.core_structs
213+
.vfprintf_internal
96214
libc.src.__support.arg_list
97-
libc.src.__support.OSUtil.osutil
98-
libc.src.__support.libc_errno
99-
libc.src.__support.CPP.limits
100215
)
101216

102217
add_entrypoint_object(

0 commit comments

Comments
 (0)