Skip to content

Commit 7318c28

Browse files
committedJan 14, 2024
[ext] Catch missing :printf module
Accidental use of printf will use the Newlib implementation which uses heap, thus causing an error message about missing :platform:heap module.
1 parent d1a6984 commit 7318c28

File tree

5 files changed

+133
-19
lines changed

5 files changed

+133
-19
lines changed
 

‎ext/eyalroz/module.lb

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ def prepare(module, options):
1919

2020
def build(env):
2121
env.collect(":build:path.include", "modm/ext")
22-
env.collect(":build:ccflags", "-fno-builtin-printf")
2322
env.outbasepath = "modm/ext/printf"
2423

2524
env.copy("printf/src/printf/printf.h", "printf.h")

‎ext/eyalroz/module.md

+21
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,24 @@ extern "C" void putchar_(char c)
4444
// MODM_LOG_INFO << c;
4545
}
4646
```
47+
48+
49+
## printf is not implemented Error
50+
51+
This module is not included by default and any attempt to use any of the printf
52+
methods fails with one or multiple linker error messages similiar to this:
53+
54+
```
55+
`printf' referenced in section `.text.startup.main'
56+
of main.o: defined in discarded section
57+
`.printf_is_not_implemented!_
58+
_Please_include_the__modm:printf__module_in_your_project!'
59+
of libmodm.a(no_printf.o)
60+
```
61+
62+
This is to prevent you from *accidentally* using the Newlib implementation of
63+
printf, which is very expensive and also dynamically allocated memory.
64+
You can either:
65+
66+
1. Include this module, which provides a fast printf implementation.
67+
2. Provide your own implementation by strongly linking against printf functions.

‎ext/eyalroz/no_printf.c.in

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2024, Niklas Hauser
3+
*
4+
* This file is part of the modm project.
5+
*
6+
* This Source Code Form is subject to the terms of the Mozilla Public
7+
* License, v. 2.0. If a copy of the MPL was not distributed with this
8+
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
9+
*/
10+
// ----------------------------------------------------------------------------
11+
12+
#include <stdarg.h>
13+
#include <stddef.h>
14+
#include <modm/architecture/utils.hpp>
15+
16+
// ----------------------------------------------------------------------------
17+
modm_weak modm_section("{{ no_printf_section }}")
18+
int vprintf(const char* format, va_list arg)
19+
{
20+
(void) format;
21+
(void) arg;
22+
return 0;
23+
}
24+
25+
modm_weak modm_section("{{ no_printf_section }}")
26+
int vsnprintf(char* s, size_t n, const char* format, va_list arg)
27+
{
28+
(void) s;
29+
(void) n;
30+
(void) format;
31+
(void) arg;
32+
return 0;
33+
}
34+
35+
modm_weak modm_section("{{ no_printf_section }}")
36+
int vsprintf(char* s, const char* format, va_list arg)
37+
{
38+
(void) s;
39+
(void) format;
40+
(void) arg;
41+
return 0;
42+
}
43+
44+
modm_weak modm_section("{{ no_printf_section }}")
45+
int vfctprintf(void (*out)(char c, void* extra_arg), void* extra_arg, const char* format, va_list arg)
46+
{
47+
(void) out;
48+
(void) extra_arg;
49+
(void) format;
50+
(void) arg;
51+
return 0;
52+
}
53+
54+
modm_weak modm_section("{{ no_printf_section }}")
55+
int printf(const char* format, ...)
56+
{
57+
(void) format;
58+
return 0;
59+
}
60+
61+
modm_weak modm_section("{{ no_printf_section }}")
62+
int sprintf(char* s, const char* format, ...)
63+
{
64+
(void) s;
65+
(void) format;
66+
return 0;
67+
}
68+
69+
modm_weak modm_section("{{ no_printf_section }}")
70+
int snprintf(char* s, size_t n, const char* format, ...)
71+
{
72+
(void) s;
73+
(void) n;
74+
(void) format;
75+
return 0;
76+
}
77+
78+
modm_weak modm_section("{{ no_printf_section }}")
79+
int fctprintf(void (*out)(char c, void* extra_arg), void* extra_arg, const char* format, ...)
80+
{
81+
(void) out;
82+
(void) extra_arg;
83+
(void) format;
84+
return 0;
85+
}

‎src/modm/platform/core/cortex/linker.macros

+15-18
Original file line numberDiff line numberDiff line change
@@ -231,14 +231,8 @@ MAIN_STACK_SIZE = {{ options[":platform:cortex-m:main_stack_size"] }};
231231
. = ALIGN(4);
232232
__assertion_table_end = .;
233233
} >{{memory}}
234-
235-
/* We do not call static destructors ever */
236-
/DISCARD/ :
237-
{
238-
*(.fini_array .fini_array.*)
239-
}
240-
%% if with_cpp_exceptions
241234
%#
235+
%% if with_cpp_exceptions
242236
/* C++ exception unwind tables */
243237
.exidx :
244238
{
@@ -257,24 +251,27 @@ MAIN_STACK_SIZE = {{ options[":platform:cortex-m:main_stack_size"] }};
257251

258252
/* required by libc __libc_fini_array, but never called */
259253
_fini = .;
260-
%% else
261-
%#
262-
/* C++ exception unwind tables are discarded */
254+
%% endif
255+
263256
/DISCARD/ :
264257
{
258+
/* We do not call static destructors ever */
259+
*(.fini_array .fini_array.*)
260+
%% if not with_cpp_exceptions
261+
/* C++ exception unwind tables are discarded */
265262
*(.ARM.extab* .gnu.linkonce.armextab.*)
266263
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
267264
*(.eh_frame*)
268-
}
269-
%% endif
270-
%% if not with_heap
271-
%#
272-
/* Catch use of dynamic memory without `modm:platform:heap` module. */
273-
/DISCARD/ :
274-
{
265+
%% endif
266+
%% if not with_heap
267+
/* Catch use of dynamic memory without `modm:platform:heap` module. */
275268
*({{no_heap_section}})
269+
%% endif
270+
%% if not with_printf
271+
/* Catch use of printf without `modm:printf` module. */
272+
*({{no_printf_section}})
273+
%% endif
276274
}
277-
%% endif
278275
%% endmacro
279276

280277

‎src/modm/platform/core/cortex/module.lb

+12
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,11 @@ def common_memories(env):
127127
# See :platform:heap for explanation
128128
common_no_heap_section = (".Heap_is_not_implemented!__"
129129
"Please_include_the__modm:platform:heap__module_in_your_project!")
130+
# See :printf for explanation
131+
common_no_printf_section = (".printf_is_not_implemented!__"
132+
"Please_include_the__modm:printf__module_in_your_project!")
133+
134+
130135

131136
def common_linkerscript(env):
132137
"""
@@ -170,8 +175,10 @@ def common_linkerscript(env):
170175

171176
"with_cpp_exceptions": env.get(":stdc++:exceptions", False),
172177
"with_heap": env.has_module(":platform:heap"),
178+
"with_printf": env.has_module(":printf"),
173179
"with_crashcatcher": env.has_module(":crashcatcher"),
174180
"no_heap_section": common_no_heap_section,
181+
"no_printf_section": common_no_printf_section,
175182
}
176183
properties.update(common_memories(env))
177184
return properties
@@ -336,6 +343,11 @@ def build(env):
336343
if not env.has_module(":platform:heap"):
337344
env.substitutions["no_heap_section"] = common_no_heap_section
338345
env.template("../../heap/cortex/no_heap.c.in", "no_heap.c")
346+
# Deprecate printf functions if not implemented!
347+
env.collect(":build:ccflags", "-fno-builtin-printf")
348+
if not env.has_module(":printf"):
349+
env.substitutions["no_printf_section"] = common_no_printf_section
350+
env.template(repopath("ext/eyalroz/no_printf.c.in"), "no_printf.c")
339351

340352
if env.has_module(":architecture:atomic"):
341353
env.template("atomic_lock_impl.hpp.in")

0 commit comments

Comments
 (0)
Failed to load comments.