From 5d1f438eabac6fc4e50287f51673005d62635b01 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 28 Sep 2026 19:25:16 +0000 Subject: [PATCH] libsystemd: relocate the stream redirection keys through .got libsystemd_build_streams() initialized its local {handle, "key"} table straight from string literals. GCC copies such a table from .data, where the pointers hold link-time addresses, and the module loader only relocates .got - so on target every key pointed into unrelated memory. It went unnoticed while the strings sat below 0x4000: on STM32F7 that is the (readable) 16 KiB ITCM, the lookups just never matched and stream redirections were silently ignored. Since v0.11 the module is larger, "stdin" landed at 0x4000 and every service start HardFaulted in dmini_get_string()/strcmp (BusFault, BFAR=0x4000), e.g. dmdevmon@dmsdio0 on STM32F746G-DISCO. The keys are now DMOD_GLOBAL_POINTER variables, which live in .got and are relocated by the loader. The Cortex-M7 build has no initialized .data left. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01TgkwHQKqf6c4DzypSKzZT7 --- app/libsystemd/src/serviceapi.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/app/libsystemd/src/serviceapi.c b/app/libsystemd/src/serviceapi.c index 2043fa0..ecb58f0 100644 --- a/app/libsystemd/src/serviceapi.c +++ b/app/libsystemd/src/serviceapi.c @@ -1583,6 +1583,13 @@ static bool libsystemd_build_argv(libsystemd_service_t service, const char* exec return true; } +// Relocated by the module loader (.got) - a pointer initialized with a +// string literal elsewhere keeps its link-time address on target. +static const char* libsystemd_key_stdin DMOD_GLOBAL_POINTER = "stdin"; +static const char* libsystemd_key_stdout DMOD_GLOBAL_POINTER = "stdout"; +static const char* libsystemd_key_stderr DMOD_GLOBAL_POINTER = "stderr"; +static const char* libsystemd_key_stdlog DMOD_GLOBAL_POINTER = "stdlog"; + /** * @brief Build a service's stream redirection table from its "stdin"/"stdout"/"stderr"/"stdlog" ini keys * @@ -1614,10 +1621,10 @@ static bool libsystemd_build_streams(dmini_context_t ctx, libsystemd_service_t s void* handle; const char* key; } candidates[4] = { - { DMOD_STDIN, "stdin" }, - { DMOD_STDOUT, "stdout" }, - { DMOD_STDERR, "stderr" }, - { DMOD_STDLOG, "stdlog" }, + { DMOD_STDIN, libsystemd_key_stdin }, + { DMOD_STDOUT, libsystemd_key_stdout }, + { DMOD_STDERR, libsystemd_key_stderr }, + { DMOD_STDLOG, libsystemd_key_stdlog }, }; Dmod_StreamRedirection_t* entries = Dmod_Malloc(sizeof(Dmod_StreamRedirection_t) * 4);