Skip to content

riscv: userspace: undefined symbol: z_stack_space_get  #98491

@RobinKastberg

Description

@RobinKastberg

Describe the bug

While building qemu_riscv64 with lld, and code model large, I get undefined symbol z_stack_space_get.
Taking a look this actually seems to be true.
Since:

#if defined(CONFIG_INIT_STACKS) && defined(CONFIG_THREAD_STACK_INFO)

introduced in #22520 guards the definition of z_stack_space_get, but not the usage in arch_thread_priv_stack_space_get
return z_stack_space_get((void *)thread->arch.priv_stack_start, *stack_size, unused_ptr);

which is guarded by

#ifdef CONFIG_USERSPACE

there is also CONFIG_ARCH_HAS_THREAD_PRIV_STACK_SPACE_GET introduced in #77425 guarding the definition of arch_thread_priv_stack_space_get in the headers, but not the compilation unit itself, which is unconditionally compiled.

I have a workaround currently, but I get the feeling that someone more knowledgable of this should take a look and decide how it SHOULD work. There are multiple paths towards a solution

  • a separate function definition
  • making the Kconfig variable actually conditionally compile this properly
  • syncing up whether to check for USERSPACE and/or INIT_STACKS
diff --git a/arch/riscv/core/thread.c b/arch/riscv/core/thread.c index 773bf51479a..0da917191ab 100644 --- a/arch/riscv/core/thread.c +++ b/arch/riscv/core/thread.c @@ -207,6 +207,9 @@ FUNC_NORETURN void arch_user_mode_enter(k_thread_entry_t user_entry, int arch_thread_priv_stack_space_get(const struct k_thread *thread, size_t *stack_size, size_t *unused_ptr) { +#if !defined(CONFIG_INIT_STACKS) || !defined(CONFIG_THREAD_STACK_INFO) + return -EINVAL; +#endif if ((thread->base.user_options & K_USER) != K_USER) { return -EINVAL; } 

Regression

  • This is a regression.

Steps to reproduce

LLVM_TOOLCHAIN_PATH=/workdir/llvm/build/ ZEPHYR_TOOLCHAIN_VARIANT=llvm west build -p -b qemu_riscv64 samples/userspace/hello_world_user/ -DCONFIG_LLVM_USE_LLD=y -DCONFIG_COMPILER_RT_RTLIB=y

Relevant log output

ld.lld: error: undefined symbol: z_stack_space_get >>> referenced by thread.c >>> thread.c.obj:(.data.rel.ro+0x58) in archive zephyr/arch/arch/riscv/core/libarch__riscv__core.a clang: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped: subcommand failed.

Impact

Major – Severely degrades functionality; workaround is difficult or unavailable.

Environment

f39f9bd

Additional Context

Why is this only being discovered in some special cases?
I guess because linker will cull symbols not being used, is there some way to detect all undefined symbols?

Metadata

Metadata

Labels

area: RISCVRISCV Architecture (32-bit & 64-bit)area: UserspaceUserspacebugThe issue is a bug, or the PR is fixing a bugpriority: highHigh impact/importance bug

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions