Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Catch missing printf implementation #1120

Merged
merged 1 commit into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ext/eyalroz/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ def prepare(module, options):

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

env.copy("printf/src/printf/printf.h", "printf.h")
Expand Down
21 changes: 21 additions & 0 deletions ext/eyalroz/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,24 @@ extern "C" void putchar_(char c)
// MODM_LOG_INFO << c;
}
```


## printf is not implemented Error

This module is not included by default and any attempt to use any of the printf
methods fails with one or multiple linker error messages similiar to this:

```
`printf' referenced in section `.text.startup.main'
of main.o: defined in discarded section
`.printf_is_not_implemented!_
_Please_include_the__modm:printf__module_in_your_project!'
of libmodm.a(no_printf.o)
```

This is to prevent you from *accidentally* using the Newlib implementation of
printf, which is very expensive and also dynamically allocated memory.
You can either:

1. Include this module, which provides a fast printf implementation.
2. Provide your own implementation by strongly linking against printf functions.
85 changes: 85 additions & 0 deletions ext/eyalroz/no_printf.c.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/*
* Copyright (c) 2024, Niklas Hauser
*
* This file is part of the modm project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
// ----------------------------------------------------------------------------

#include <stdarg.h>
#include <stddef.h>
#include <modm/architecture/utils.hpp>

// ----------------------------------------------------------------------------
modm_weak modm_section("{{ no_printf_section }}")
int vprintf(const char* format, va_list arg)
{
(void) format;
(void) arg;
return 0;
}

modm_weak modm_section("{{ no_printf_section }}")
int vsnprintf(char* s, size_t n, const char* format, va_list arg)
{
(void) s;
(void) n;
(void) format;
(void) arg;
return 0;
}

modm_weak modm_section("{{ no_printf_section }}")
int vsprintf(char* s, const char* format, va_list arg)
{
(void) s;
(void) format;
(void) arg;
return 0;
}

modm_weak modm_section("{{ no_printf_section }}")
int vfctprintf(void (*out)(char c, void* extra_arg), void* extra_arg, const char* format, va_list arg)
{
(void) out;
(void) extra_arg;
(void) format;
(void) arg;
return 0;
}

modm_weak modm_section("{{ no_printf_section }}")
int printf(const char* format, ...)
{
(void) format;
return 0;
}

modm_weak modm_section("{{ no_printf_section }}")
int sprintf(char* s, const char* format, ...)
{
(void) s;
(void) format;
return 0;
}

modm_weak modm_section("{{ no_printf_section }}")
int snprintf(char* s, size_t n, const char* format, ...)
{
(void) s;
(void) n;
(void) format;
return 0;
}

modm_weak modm_section("{{ no_printf_section }}")
int fctprintf(void (*out)(char c, void* extra_arg), void* extra_arg, const char* format, ...)
{
(void) out;
(void) extra_arg;
(void) format;
return 0;
}
33 changes: 15 additions & 18 deletions src/modm/platform/core/cortex/linker.macros
Original file line number Diff line number Diff line change
Expand Up @@ -231,14 +231,8 @@ MAIN_STACK_SIZE = {{ options[":platform:cortex-m:main_stack_size"] }};
. = ALIGN(4);
__assertion_table_end = .;
} >{{memory}}

/* We do not call static destructors ever */
/DISCARD/ :
{
*(.fini_array .fini_array.*)
}
%% if with_cpp_exceptions
%#
%% if with_cpp_exceptions
/* C++ exception unwind tables */
.exidx :
{
Expand All @@ -257,24 +251,27 @@ MAIN_STACK_SIZE = {{ options[":platform:cortex-m:main_stack_size"] }};

/* required by libc __libc_fini_array, but never called */
_fini = .;
%% else
%#
/* C++ exception unwind tables are discarded */
%% endif

/DISCARD/ :
{
/* We do not call static destructors ever */
*(.fini_array .fini_array.*)
%% if not with_cpp_exceptions
/* C++ exception unwind tables are discarded */
*(.ARM.extab* .gnu.linkonce.armextab.*)
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
*(.eh_frame*)
}
%% endif
%% if not with_heap
%#
/* Catch use of dynamic memory without `modm:platform:heap` module. */
/DISCARD/ :
{
%% endif
%% if not with_heap
/* Catch use of dynamic memory without `modm:platform:heap` module. */
*({{no_heap_section}})
%% endif
%% if not with_printf
/* Catch use of printf without `modm:printf` module. */
*({{no_printf_section}})
%% endif
}
%% endif
%% endmacro


Expand Down
12 changes: 12 additions & 0 deletions src/modm/platform/core/cortex/module.lb
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,11 @@ def common_memories(env):
# See :platform:heap for explanation
common_no_heap_section = (".Heap_is_not_implemented!__"
"Please_include_the__modm:platform:heap__module_in_your_project!")
# See :printf for explanation
common_no_printf_section = (".printf_is_not_implemented!__"
"Please_include_the__modm:printf__module_in_your_project!")



def common_linkerscript(env):
"""
Expand Down Expand Up @@ -170,8 +175,10 @@ def common_linkerscript(env):

"with_cpp_exceptions": env.get(":stdc++:exceptions", False),
"with_heap": env.has_module(":platform:heap"),
"with_printf": env.has_module(":printf"),
"with_crashcatcher": env.has_module(":crashcatcher"),
"no_heap_section": common_no_heap_section,
"no_printf_section": common_no_printf_section,
}
properties.update(common_memories(env))
return properties
Expand Down Expand Up @@ -336,6 +343,11 @@ def build(env):
if not env.has_module(":platform:heap"):
env.substitutions["no_heap_section"] = common_no_heap_section
env.template("../../heap/cortex/no_heap.c.in", "no_heap.c")
# Deprecate printf functions if not implemented!
env.collect(":build:ccflags", "-fno-builtin-printf")
if not env.has_module(":printf"):
env.substitutions["no_printf_section"] = common_no_printf_section
env.template(repopath("ext/eyalroz/no_printf.c.in"), "no_printf.c")

if env.has_module(":architecture:atomic"):
env.template("atomic_lock_impl.hpp.in")
Expand Down
Loading