Skip to content

Commit 7707060

Browse files
Andrew Boieandrewboie
authored andcommitted
userspace: get rid of app section placeholders
We used to leave byte-long placeholder symbols to ensure that empty application memory sections did not cause build errors that were very difficult to understand. Now we use some relatively portable inline assembly to generate a symbol, but don't take up any extra space. The malloc and libc partitions are now only instantiated if there is some data to put in them. Fixes: #13923 Signed-off-by: Andrew Boie <[email protected]>
1 parent 475d279 commit 7707060

File tree

5 files changed

+53
-8
lines changed

5 files changed

+53
-8
lines changed

include/app_memory/app_memdomain.h

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,37 @@ struct z_app_region {
6767
#define Z_APP_BSS_START(id) data_smem_##id##_bss_start
6868
#define Z_APP_BSS_SIZE(id) data_smem_##id##_bss_size
6969

70+
/* If a partition is declared with K_APPMEM_PARTITION, but never has any
71+
* data assigned to its contents, then no symbols with its prefix will end
72+
* up in the symbol table. This prevents gen_app_partitions.py from detecting
73+
* that the partition exists, and the linker symbols which specify partition
74+
* bounds will not be generated, resulting in build errors.
75+
*
76+
* What this inline assembly code does is define a symbol with no data.
77+
* This should work for all arches that produce ELF binaries, see
78+
* https://sourceware.org/binutils/docs/as/Section.html
79+
*
80+
* We don't know what active flags/type of the pushed section were, so we are
81+
* specific: "aw" indicates section is allocatable and writable,
82+
* and "@progbits" indicates the section has data.
83+
*/
84+
#ifdef CONFIG_ARM
85+
/* ARM has a quirk in that '@' denotes a comment, so we have to send
86+
* %progbits to the assembler instead.
87+
*/
88+
#define Z_PROGBITS_SYM "\%"
89+
#else
90+
#define Z_PROGBITS_SYM "@"
91+
#endif
92+
93+
#define Z_APPMEM_PLACEHOLDER(name) \
94+
__asm__ ( \
95+
".pushsection " STRINGIFY(K_APP_DMEM_SECTION(name)) \
96+
",\"aw\"," Z_PROGBITS_SYM "progbits\n\t" \
97+
".global " STRINGIFY(name) "_placeholder\n\t" \
98+
STRINGIFY(name) "_placeholder:\n\t" \
99+
".popsection\n\t")
100+
70101
/**
71102
* @brief Define an application memory partition with linker support
72103
*
@@ -94,8 +125,7 @@ struct z_app_region {
94125
.bss_start = &Z_APP_BSS_START(name), \
95126
.bss_size = (size_t) &Z_APP_BSS_SIZE(name) \
96127
}; \
97-
K_APP_BMEM(name) char name##_placeholder;
98-
128+
Z_APPMEM_PLACEHOLDER(name);
99129
#else
100130

101131
#define K_APP_BMEM(ptn)

include/misc/libc-hooks.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,23 @@ __syscall size_t _zephyr_fwrite(const void *_MLIBC_RESTRICT ptr, size_t size,
3737
#endif /* CONFIG_NEWLIB_LIBC */
3838

3939
#ifdef CONFIG_USERSPACE
40+
#if defined(CONFIG_NEWLIB_LIBC) || (CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE > 0)
41+
#define Z_MALLOC_PARTITION_EXISTS 1
42+
4043
/* Memory partition containing the libc malloc arena */
4144
extern struct k_mem_partition z_malloc_partition;
45+
#endif
46+
47+
#if defined(CONFIG_NEWLIB_LIBC) || defined(CONFIG_STACK_CANARIES)
48+
/* Minimal libc has no globals. We do put the stack canary global in the
49+
* libc partition since it is not worth placing in a partition of its own.
50+
*/
51+
#define Z_LIBC_PARTITION_EXISTS 1
4252

4353
/* C library globals, except the malloc arena */
4454
extern struct k_mem_partition z_libc_partition;
4555
#endif
56+
#endif /* CONFIG_USERSPACE */
4657

4758
#include <syscalls/libc-hooks.h>
4859

kernel/userspace.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@
1818
#include <init.h>
1919
#include <stdbool.h>
2020
#include <app_memory/app_memdomain.h>
21+
#include <misc/libc-hooks.h>
2122

23+
#ifdef Z_LIBC_PARTITION_EXISTS
2224
K_APPMEM_PARTITION_DEFINE(z_libc_partition);
25+
#endif
2326

2427
#define LOG_LEVEL CONFIG_KERNEL_LOG_LEVEL
2528
#include <logging/log.h>

lib/libc/minimal/source/stdlib/malloc.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,9 @@
1616
#include <logging/log.h>
1717
LOG_MODULE_DECLARE(os);
1818

19-
#ifdef CONFIG_USERSPACE
20-
K_APPMEM_PARTITION_DEFINE(z_malloc_partition);
21-
#endif
22-
2319
#if (CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE > 0)
2420
#ifdef CONFIG_USERSPACE
21+
K_APPMEM_PARTITION_DEFINE(z_malloc_partition);
2522
#define POOL_SECTION K_APP_DMEM_SECTION(z_malloc_partition)
2623
#else
2724
#define POOL_SECTION .data

subsys/testsuite/ztest/src/ztest.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,15 @@ void main(void)
301301
{
302302
#ifdef CONFIG_USERSPACE
303303
struct k_mem_partition *parts[] = {
304-
&ztest_mem_partition,
304+
#ifdef Z_LIBC_PARTITION_EXISTS
305305
/* C library globals, stack canary storage, etc */
306306
&z_libc_partition,
307+
#endif
308+
#ifdef Z_MALLOC_PARTITION_EXISTS
307309
/* Required for access to malloc arena */
308-
&z_malloc_partition
310+
&z_malloc_partition,
311+
#endif
312+
&ztest_mem_partition
309313
};
310314

311315
/* Ztests just have one memory domain with one partition.

0 commit comments

Comments
 (0)