Skip to content

Commit d3ae3ac

Browse files
committed
CLANG: add standard I/O stream support for LLVM-libc
1 parent 9bddbf4 commit d3ae3ac

2 files changed

Lines changed: 179 additions & 2 deletions

File tree

ARM.CMSIS-Compiler.pdsc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
<releases>
1616
<release version="2.2.1-dev">
1717
Active Development ...
18+
CLANG:
19+
- Added standard I/O stream support for LLVM-libc
1820
</release>
1921
</releases>
2022

@@ -245,7 +247,7 @@
245247
<file category="header" name="config/stdio_cmsis_uart_config.h" attr="config" version="1.0.0" condition="STDIO UART CMSIS"/>
246248
</files>
247249
</component>
248-
<component Cclass="CMSIS-Compiler" Cgroup="CORE" Cversion="1.2.0" condition="CLANG CortexDevice">
250+
<component Cclass="CMSIS-Compiler" Cgroup="CORE" Cversion="1.3.0" condition="CLANG CortexDevice">
249251
<description>Standard C Library Retarget Core</description>
250252
<files>
251253
<file category="sourceC" name="source/core/clang/retarget_syscalls.c"/>

source/core/clang/retarget_syscalls.c

Lines changed: 176 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,181 @@
4141
#endif
4242
#endif
4343

44+
#ifndef STDIN_ECHO
45+
#define STDIN_ECHO 0 /* STDIN: echo to STDOUT */
46+
#endif
47+
#ifndef STDOUT_CR_LF
48+
#define STDOUT_CR_LF 0 /* STDOUT: add CR for LF */
49+
#endif
50+
#ifndef STDERR_CR_LF
51+
#define STDERR_CR_LF 0 /* STDERR: add CR for LF */
52+
#endif
53+
54+
#if defined(__LLVM_LIBC__)
55+
56+
/* Symbols used as cookie values to identify standard I/O stream */
57+
void *__llvm_libc_stdin_cookie = NULL;
58+
void *__llvm_libc_stdout_cookie = NULL;
59+
void *__llvm_libc_stderr_cookie = NULL;
60+
61+
/**
62+
Write bytes to a standard output stream.
63+
64+
Called by LLVM-libc for all stdout/stderr writes. The cookie parameter
65+
identifies the target stream: it matches the address of the
66+
__llvm_libc_stdout_cookie or __llvm_libc_stderr_cookie symbol.
67+
68+
\param[in] cookie Stream identifier
69+
\param[in] buf Pointer to data buffer
70+
\param[in] size Number of bytes to write
71+
\return Number of bytes written, or -1 on error.
72+
*/
73+
__attribute__((weak))
74+
ssize_t __llvm_libc_stdio_write(void *cookie, const char *buf, size_t size) {
75+
#if (defined(RTE_CMSIS_Compiler_STDOUT) || defined(RTE_CMSIS_Compiler_STDERR))
76+
int ch;
77+
ssize_t sz = 0;
78+
const char *p = buf;
79+
#else
80+
(void)cookie;
81+
(void)buf;
82+
(void)size;
83+
#endif
84+
85+
#if defined(RTE_CMSIS_Compiler_STDOUT)
86+
if (cookie == &__llvm_libc_stdout_cookie) {
87+
while (sz < (ssize_t)size) {
88+
ch = *p++;
89+
#if (STDOUT_CR_LF != 0)
90+
if (ch == '\n') {
91+
if (stdout_putchar('\r') == -1) {
92+
break;
93+
}
94+
}
95+
#endif
96+
if (stdout_putchar(ch) == -1) {
97+
break;
98+
}
99+
sz++;
100+
}
101+
return (sz);
102+
}
103+
#endif
104+
105+
#if defined(RTE_CMSIS_Compiler_STDERR)
106+
if (cookie == &__llvm_libc_stderr_cookie) {
107+
while (sz < (ssize_t)size) {
108+
ch = *p++;
109+
#if (STDERR_CR_LF != 0)
110+
if (ch == '\n') {
111+
if (stderr_putchar('\r') == -1) {
112+
break;
113+
}
114+
}
115+
#endif
116+
if (stderr_putchar(ch) == -1) {
117+
break;
118+
}
119+
sz++;
120+
}
121+
return (sz);
122+
}
123+
#endif
124+
/* Not implemented */
125+
return (-1);
126+
}
127+
128+
/**
129+
Read bytes from stdin.
130+
131+
Called by LLVM-libc for all stdin reads. The cookie parameter matches the
132+
address of the __llvm_libc_stdin_cookie symbol.
133+
134+
\param[in] cookie Stream identifier
135+
\param[out] buf Pointer to data buffer
136+
\param[in] size Maximum number of bytes to read
137+
\return Number of bytes read (> 0), 0 on end of input,
138+
or a negative errno value on error.
139+
*/
140+
__attribute__((weak))
141+
ssize_t __llvm_libc_stdio_read(void *cookie, char *buf, size_t size) {
142+
#if defined(RTE_CMSIS_Compiler_STDIN)
143+
int ch;
144+
ssize_t sz = 0;
145+
char *p = buf;
146+
#else
147+
(void)cookie;
148+
(void)buf;
149+
(void)size;
150+
#endif
151+
152+
#if defined(RTE_CMSIS_Compiler_STDIN)
153+
if (cookie == &__llvm_libc_stdin_cookie) {
154+
while (sz < (ssize_t)size) {
155+
ch = stdin_getchar();
156+
if (ch < 0) {
157+
break;
158+
}
159+
*p++ = (char)ch;
160+
#if (STDIN_ECHO != 0)
161+
stdout_putchar(ch);
162+
#endif
163+
sz++;
164+
}
165+
return sz;
166+
}
167+
#endif
168+
/* Not implemented */
169+
return (-1);
170+
}
171+
172+
/**
173+
Terminate a process.
174+
175+
Called by LLVM-libc for all process termination.
176+
The status parameter is the exit code passed to the exit() function. This
177+
implementation does not support process termination, so it simply enters
178+
an infinite loop.
179+
180+
\param[in] status Exit code passed to exit()
181+
*/
182+
__attribute__((weak, __noreturn__))
183+
void __llvm_libc_exit(int status) {
184+
(void)status;
185+
for (;;) { ; }
186+
}
187+
188+
/**
189+
Set up the exceptions table and enable relevant interrupts.
190+
191+
This function overrides crt0's _platform_setup_exceptions which sets VTOR
192+
to its own minimal 16-entry vector table, breaking device IRQ handlers.
193+
Restoring VTOR to the full CMSIS vector table (256 entries) ensures device-
194+
specific interrupt vectors are resolved correctly.
195+
*/
196+
__attribute__((weak))
197+
void _platform_setup_exceptions (void) {}
198+
199+
/**
200+
Set up the Memory Management Unit and caches.
201+
202+
This function overrides crt0's _platform_setup_memory which may override settings
203+
applied in vendor specific SystemInit.
204+
*/
205+
__attribute__((weak))
206+
void _platform_setup_memory (void) {}
207+
208+
/**
209+
Set up architecture extensions that require special initialization.
210+
211+
This function overrides crt0's _platform_setup_arch_extensions which may override
212+
settings applied in vendor specific SystemInit.
213+
*/
214+
__attribute__((weak))
215+
void _platform_setup_arch_extensions (void) {}
216+
217+
#elif defined(__PICOLIBC_VERSION__)
218+
44219
#if defined(RTE_CMSIS_Compiler_STDIN)
45220
/**
46221
Get a character from the stdio
@@ -93,7 +268,6 @@ static FILE __stdout = FDEV_SETUP_STREAM(stdout_putc,
93268
FILE *const stdout = &__stdout;
94269
#endif
95270

96-
97271
#if defined(RTE_CMSIS_Compiler_STDERR)
98272
/**
99273
Put a character to the stderr
@@ -125,3 +299,4 @@ __attribute__((weak, __noreturn__))
125299
void _exit (int status) {
126300
for(;;){ ; }
127301
}
302+
#endif /* __LLVM_LIBC__ */

0 commit comments

Comments
 (0)