public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/9] nolibc: Add static-pie support
@ 2026-01-31  7:44 Daniel Palmer
  2026-01-31  7:44 ` [RFC PATCH 1/9] elf: Add relocation types used by nolibc Daniel Palmer
                   ` (9 more replies)
  0 siblings, 10 replies; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

For more background see:
https://lore.kernel.org/lkml/20260116122812.2421621-1-daniel@thingy.jp/

Basically I am trying to run normal ELF binaries created with
nolibc on nommu (m68k, 68000). To make this work without an external
linker nolibc needs code to do the relocation.

The following is my attempt at doing this by hacking just enough
together that static-pie binaries work on a few archs.
The ones that work have a patch in this series.

Answers to questions you might have:
Q: Don't we need to handle more relocation types?
A: Maybe, everything exception sparc only had R_x_RELATIVE in
   the nolibc test binary. sparc emits R_SPARC_NONE as well.

Q: Don't we need to make some sections writable for this to
   work.
A: Maybe, I tried to get most of the supported archs working.
   The only one that had relocations on a non-writable section
   was arm64 and I think I can fix it so it doesn't need that.

Q: Why can't you just pass -static-pie to gcc?
A: Only x86 seemed to actually produce static PIE binaries doing
   that. Everything else produced normal static ones. Maybe this
   is a compiler version thing?

There are probably things I'm missing, things I have done totally
wrong. Please feel free to grill me.

Daniel Palmer (9):
  elf: Add relocation types used by nolibc
  tools/nolibc: crt: Split _start_c() into stack-only and normal part
  tools/nolibc: Add basic ELF self-relocation support for static PIE
  tools/nolibc: m68k: Add relocation support
  tools/nolibc: x86: Add relocation support for x86_64
  tools/nolibc: riscv: Add relocation support
  tools/nolibc: arm: Add relocation support
  selftests/nolibc: Add option for building with -static-pie
  fs/binfmt_elf_fdpic: Reflect that PIE binaries also work in KConfig
    help

 fs/Kconfig.binfmt                             |  10 +
 include/uapi/linux/elf-r.h                    |  27 ++
 include/uapi/linux/elf.h                      |   1 +
 tools/include/nolibc/Makefile                 |   1 +
 tools/include/nolibc/arch-arm.h               |  17 ++
 tools/include/nolibc/arch-m68k.h              |  20 +-
 tools/include/nolibc/arch-riscv.h             |  18 ++
 tools/include/nolibc/arch-x86.h               |  35 +++
 tools/include/nolibc/crt.h                    |  62 +++--
 tools/include/nolibc/reloc.h                  | 240 ++++++++++++++++++
 tools/testing/selftests/nolibc/Makefile       |   2 +-
 .../testing/selftests/nolibc/Makefile.nolibc  |   8 +-
 tools/testing/selftests/nolibc/run-tests.sh   |  10 +-
 13 files changed, 423 insertions(+), 28 deletions(-)
 create mode 100644 include/uapi/linux/elf-r.h
 create mode 100644 tools/include/nolibc/reloc.h

-- 
2.51.0


^ permalink raw reply	[flat|nested] 19+ messages in thread

* [RFC PATCH 1/9] elf: Add relocation types used by nolibc
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-02-01 16:25   ` Thomas Weißschuh
  2026-01-31  7:44 ` [RFC PATCH 2/9] tools/nolibc: crt: Split _start_c() into stack-only and normal part Daniel Palmer
                   ` (8 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

nolibc based programs are gaining the ability to relocate themselves
so that they can support PIE without needing a linker or special
crt from the toolchain.

Add the required relocation types.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 include/uapi/linux/elf-r.h | 27 +++++++++++++++++++++++++++
 include/uapi/linux/elf.h   |  1 +
 2 files changed, 28 insertions(+)
 create mode 100644 include/uapi/linux/elf-r.h

diff --git a/include/uapi/linux/elf-r.h b/include/uapi/linux/elf-r.h
new file mode 100644
index 000000000000..a1dce23104a7
--- /dev/null
+++ b/include/uapi/linux/elf-r.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+#ifndef _LINUX_ELF_R_H
+#define _LINUX_ELF_R_H
+
+/* These constants define various ELF relocation types */
+#define R_386_RELATIVE		8
+
+#define R_68K_RELATIVE		22
+
+#define R_AARCH64_RELATIVE	1027
+
+#define R_AMD64_RELATIVE	8
+
+#define R_ARM_RELATIVE		23
+
+#define R_LARCH_RELATIVE	3
+
+#define R_PPC_RELATIVE		22
+
+#define R_RISCV_RELATIVE	3
+
+#define R_SH_RELATIVE		165
+
+#define R_SPARC_NONE		0
+#define R_SPARC_RELATIVE	22
+
+#endif /* _LINUX_ELF_R_H */
diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
index 819ded2d39de..3d18543d5460 100644
--- a/include/uapi/linux/elf.h
+++ b/include/uapi/linux/elf.h
@@ -4,6 +4,7 @@
 
 #include <linux/types.h>
 #include <linux/elf-em.h>
+#include <linux/elf-r.h>
 
 /* 32-bit ELF base types. */
 typedef __u32	Elf32_Addr;
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 2/9] tools/nolibc: crt: Split _start_c() into stack-only and normal part
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
  2026-01-31  7:44 ` [RFC PATCH 1/9] elf: Add relocation types used by nolibc Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-02-01 16:33   ` Thomas Weißschuh
  2026-01-31  7:44 ` [RFC PATCH 3/9] tools/nolibc: Add basic ELF self-relocation support for static PIE Daniel Palmer
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

To prepare for nolibc programs being able to relocate themselves
we need to split _start_c() into two parts:

- One part that only uses the stack so there are no accesses via
  the GOT etc that isn't setup yet. Note that on m68k at least
  this also means forcing the stackprotector off because accessing
  the stack protector canary is done via the GOT.

- Another part that is called after we have done relocation so it
  is safe to access global variables etc that might use the GOT etc.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 tools/include/nolibc/crt.h | 57 +++++++++++++++++++++++---------------
 1 file changed, 35 insertions(+), 22 deletions(-)

diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index d9262998dae9..899062c00fb7 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -27,26 +27,51 @@ extern void (*const __init_array_end[])(int, char **, char**) __attribute__((wea
 extern void (*const __fini_array_start[])(void) __attribute__((weak));
 extern void (*const __fini_array_end[])(void) __attribute__((weak));
 
-void _start_c(long *sp);
-__attribute__((weak,used))
+void __start_c(long argc, char **argv, char **envp, const unsigned long *auxv);
+__attribute__((weak, used))
 #if __nolibc_has_feature(undefined_behavior_sanitizer)
 	__attribute__((no_sanitize("function")))
 #endif
-void _start_c(long *sp)
+void __no_stack_protector __start_c(long argc, char **argv, char **envp, const unsigned long *auxv)
 {
-	long argc;
-	char **argv;
-	char **envp;
-	int exitcode;
 	void (* const *ctor_func)(int, char **, char **);
 	void (* const *dtor_func)(void);
-	const unsigned long *auxv;
 	/* silence potential warning: conflicting types for 'main' */
 	int _nolibc_main(int, char **, char **) __asm__ ("main");
+	int exitcode;
 
 	/* initialize stack protector */
 	__stack_chk_init();
 
+	environ = envp;
+	_auxv = auxv;
+
+	for (ctor_func = __preinit_array_start; ctor_func < __preinit_array_end; ctor_func++)
+		(*ctor_func)(argc, argv, envp);
+	for (ctor_func = __init_array_start; ctor_func < __init_array_end; ctor_func++)
+		(*ctor_func)(argc, argv, envp);
+
+	/* go to application */
+	exitcode = _nolibc_main(argc, argv, envp);
+
+	for (dtor_func = __fini_array_end; dtor_func > __fini_array_start;)
+		(*--dtor_func)();
+
+	exit(exitcode);
+}
+
+void _start_c(long *sp);
+__attribute__((weak, used))
+#if __nolibc_has_feature(undefined_behavior_sanitizer)
+	__attribute__((no_sanitize("function")))
+#endif
+void __no_stack_protector _start_c(long *sp)
+{
+	long argc;
+	char **argv;
+	char **envp;
+	const unsigned long *auxv;
+
 	/*
 	 * sp  :    argc          <-- argument count, required by main()
 	 * argv:    argv[0]       <-- argument vector, required by main()
@@ -69,25 +94,13 @@ void _start_c(long *sp)
 	argv = (void *)(sp + 1);
 
 	/* find environ */
-	environ = envp = argv + argc + 1;
+	envp = argv + argc + 1;
 
 	/* find _auxv */
 	for (auxv = (void *)envp; *auxv++;)
 		;
-	_auxv = auxv;
 
-	for (ctor_func = __preinit_array_start; ctor_func < __preinit_array_end; ctor_func++)
-		(*ctor_func)(argc, argv, envp);
-	for (ctor_func = __init_array_start; ctor_func < __init_array_end; ctor_func++)
-		(*ctor_func)(argc, argv, envp);
-
-	/* go to application */
-	exitcode = _nolibc_main(argc, argv, envp);
-
-	for (dtor_func = __fini_array_end; dtor_func > __fini_array_start;)
-		(*--dtor_func)();
-
-	exit(exitcode);
+	__start_c(argc, argv, envp, auxv);
 }
 
 #endif /* NOLIBC_NO_RUNTIME */
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 3/9] tools/nolibc: Add basic ELF self-relocation support for static PIE
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
  2026-01-31  7:44 ` [RFC PATCH 1/9] elf: Add relocation types used by nolibc Daniel Palmer
  2026-01-31  7:44 ` [RFC PATCH 2/9] tools/nolibc: crt: Split _start_c() into stack-only and normal part Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-02-01 16:42   ` Thomas Weißschuh
  2026-01-31  7:44 ` [RFC PATCH 4/9] tools/nolibc: m68k: Add relocation support Daniel Palmer
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

Currently nolibc programs cannot be compiled with -static-pie.
Which is basically no shared libraries, no interpreter, but contain
relocation information in the ELF to allow the program to be fixed
up to run at the address that the kernel loaded it to.

There might be use cases for static PIE but mine is for nommu.
The ELF FDPIC loader can actually load normal ELFs is long as they
can be relocated.

This very basic implementation does the following:

- Works out if we are PIE and need to be relocated. ELF type == ET_DYN
- Works out if we are static PIE, have no interpreter, and need to
  relocate ourselves.
- Calculates the base address using the location of the program
  headers. This is probably not correct.
- Finds the ELF relocation data.
- Calls an arch specific function to handle each of the relocations.

Note that from testing a lot of archs don't produce static PIE
binaries with the -static-pie option and you need to compile with
-pie -Wl,--no-dynamic-linker to get a static PIE binary.

Currently REL and RELA formats are supported.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 tools/include/nolibc/Makefile |   1 +
 tools/include/nolibc/crt.h    |   7 +
 tools/include/nolibc/reloc.h  | 240 ++++++++++++++++++++++++++++++++++
 3 files changed, 248 insertions(+)
 create mode 100644 tools/include/nolibc/reloc.h

diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
index 8118e22844f1..2b968a097854 100644
--- a/tools/include/nolibc/Makefile
+++ b/tools/include/nolibc/Makefile
@@ -38,6 +38,7 @@ all_files := \
 		math.h \
 		nolibc.h \
 		poll.h \
+		reloc.h \
 		sched.h \
 		signal.h \
 		stackprotector.h \
diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index 899062c00fb7..3c1c8d738ac7 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -10,6 +10,7 @@
 #ifndef NOLIBC_NO_RUNTIME
 
 #include "compiler.h"
+#include "reloc.h"
 
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
@@ -100,6 +101,12 @@ void __no_stack_protector _start_c(long *sp)
 	for (auxv = (void *)envp; *auxv++;)
 		;
 
+	/*
+	 * Do relocation if required and supported, this must happen before any
+	 * global variables are updated or used.
+	 */
+	_relocate(auxv);
+
 	__start_c(argc, argv, envp, auxv);
 }
 
diff --git a/tools/include/nolibc/reloc.h b/tools/include/nolibc/reloc.h
new file mode 100644
index 000000000000..98c42af6f845
--- /dev/null
+++ b/tools/include/nolibc/reloc.h
@@ -0,0 +1,240 @@
+/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
+/*
+ * Self relocation support for NOLIBC
+ * Copyright (C) 2026 Daniel Palmer<daniel@thingy.jp>
+ *
+ * This allows a PIE compiled nolibc binary relocate itself
+ * instead of relying on a dynamic linker. So called "static PIE".
+ *
+ * With some care binaries produced with this relocation code
+ * can run via the FDPIC ELF loader on nommu systems.
+ *
+ * I am not expert in all of the different options for GCC but
+ * this works for me for x86:
+ * gcc -nostdlib -fpie -Os -include <path to nolibc.h> \
+ * -static-pie -o helloworld helloworld.c
+ *
+ * For some targets -static-pie doesn't work but setting PIE and
+ * then disabling the linker results in a static-pie:
+ * gcc -nostdlib -fpie -Os -include <path to nolibc.h> \
+ * -Wl,--no-dynamic-linker -pie -o helloworld helloworld.c
+ */
+
+#ifndef _NOLIBC_RELOC_H
+#define _NOLIBC_RELOC_H
+
+#ifdef NOLIBC_ARCH_HAS_RELOC
+#include "elf.h"
+#include <linux/auxvec.h>
+
+#ifdef NOLIBC_ARCH_ELF32
+#define elf_ehdr Elf32_Ehdr
+#define elf_phdr Elf32_Phdr
+/* 32bit ARM, x86 uses REL instead of RELA */
+#ifdef NOLIBC_ARCH_ELF_REL
+#define elf_rel  Elf32_Rel
+#else
+#define elf_rela Elf32_Rela
+#endif
+#define elf_dyn  Elf32_Dyn
+#define elf_addr Elf32_Addr
+#define elf_r_type(_x) ELF32_R_TYPE(_x)
+#else
+#define elf_ehdr Elf64_Ehdr
+#define elf_phdr Elf64_Phdr
+#define elf_dyn  Elf64_Dyn
+#define elf_rela Elf64_Rela
+#define elf_addr Elf64_Addr
+#define elf_r_type(_x) ELF64_R_TYPE(_x)
+#endif
+
+#ifdef NOLIBC_ARCH_ELF_REL
+/*
+ * Your arch needs to provide this to actually handle doing each of the
+ * relocations if it uses the REL format.
+ */
+static int __relocate_rel(unsigned long base, elf_rel *entry);
+
+/* Generic implementation of R_x_RELATIVE for REL */
+#define __relocate_rel_relative(_base, _entry)			\
+	do {							\
+		elf_addr *_addr;				\
+		int addend;					\
+								\
+		_addr = (elf_addr *)(_base + _entry->r_offset);	\
+		addend = *_addr;				\
+		*_addr = _base + addend;			\
+	} while (0)
+
+static int __relocate(unsigned long base,
+		      unsigned long rel_off,
+		      unsigned long rel_count)
+{
+	elf_rel *rel = (elf_rel *)(base + rel_off);
+	unsigned long i;
+
+	for (i = 0; i < rel_count; i++) {
+		if (__relocate_rel(base, &rel[i]))
+			return -1;
+	}
+
+	return 0;
+}
+#else
+/*
+ * Your arch needs to provide this to actually handle doing each of the
+ * relocations if it uses the RELA format.
+ */
+static int __relocate_rela(unsigned long base, elf_rela *entry);
+
+/* Generic implementation of R_x_RELATIVE for RELA */
+#define __relocate_rela_relative(_base, _entry)			\
+	do {							\
+		elf_addr *_addr;				\
+								\
+		_addr = (elf_addr *)(_base + _entry->r_offset);	\
+		*_addr = (elf_addr) (_base + _entry->r_addend);	\
+	} while (0)
+
+static int __relocate(unsigned long base,
+		      unsigned long rela_off,
+		      unsigned long rela_count)
+{
+	elf_rela *rela = (elf_rela *)(base + rela_off);
+	unsigned long i;
+
+	for (i = 0; i < rela_count; i++) {
+		if (__relocate_rela(base, &rela[i]))
+			return -1;
+	}
+
+	return 0;
+}
+#endif
+
+static void _relocate(const unsigned long *auxv)
+{
+	unsigned long rel_rela_count = 0;
+	unsigned long rel_rela_off = 0;
+	unsigned long phdr_addr = 0;
+	unsigned long phdr_num = 0;
+	unsigned long phdr_sz = 0;
+	elf_phdr *phdr_dyn = NULL;
+	unsigned long base;
+	unsigned long i;
+	int remaining;
+	elf_ehdr *ehdr;
+	elf_dyn *dyn;
+
+	for (remaining = 3; remaining; ) {
+		if (!auxv[0] && !auxv[1])
+			break;
+
+		switch (auxv[0]) {
+		case AT_NOTELF:
+			return;
+
+		case AT_PHDR:
+			phdr_addr = auxv[1];
+			remaining--;
+			break;
+
+		case AT_PHNUM:
+			phdr_num = auxv[1];
+			remaining--;
+			break;
+
+		/*
+		 * Not sure if this is even needed, should match
+		 * the size of the program header type?
+		 */
+		case AT_PHENT:
+			phdr_sz = auxv[1];
+			remaining--;
+			break;
+		}
+
+		auxv += 2;
+	}
+
+	if (remaining)
+		goto failed;
+
+	/*
+	 * Everything I could find said that the way to find the base for relocation
+	 * should be done by searching for the first PT_LOAD and then using the ofset
+	 * of that against the adressed of the program headers. So FIXME.
+	 */
+	base = phdr_addr - sizeof(elf_ehdr);
+
+	/* Check that we are PIE */
+	ehdr = (elf_ehdr *) base;
+	if (ehdr->e_type != ET_DYN)
+		return;
+
+	for (i = 0, remaining = 1; (i < phdr_num) && remaining; i++) {
+		elf_phdr *phdr = (elf_phdr *)(phdr_addr + (phdr_sz * i));
+
+		switch (phdr->p_type) {
+		case PT_INTERP:
+			/* Interp was set, we were relocated already?, return */
+			return;
+		case PT_DYNAMIC:
+			phdr_dyn = phdr;
+			remaining--;
+			break;
+		}
+	}
+
+	if (!phdr_dyn)
+		goto failed;
+
+	dyn = (elf_dyn *)(base + phdr_dyn->p_offset);
+	for (; dyn->d_tag != DT_NULL; dyn++) {
+		switch (dyn->d_tag) {
+#ifdef NOLIBC_ARCH_ELF_REL
+		case DT_REL:
+			rel_rela_off = dyn->d_un.d_ptr;
+			break;
+		case DT_RELCOUNT:
+			rel_rela_count = dyn->d_un.d_val;
+			break;
+		}
+#else
+		case DT_RELA:
+			rel_rela_off = dyn->d_un.d_ptr;
+			break;
+		case DT_RELACOUNT:
+			rel_rela_count = dyn->d_un.d_val;
+			break;
+		}
+#endif
+
+		/* Got what we came for, exit loop */
+		if (rel_rela_off && rel_rela_count)
+			break;
+	}
+
+	if (!rel_rela_off || !rel_rela_count)
+		goto failed;
+
+	if (__relocate(base, rel_rela_off, rel_rela_count))
+		goto failed;
+
+	return;
+
+failed:
+	__builtin_trap();
+}
+#else
+static void _relocate(const unsigned long *auxv __attribute__((unused)))
+{
+	/*
+	 * Maybe if you build a program that needs relocation
+	 * but it's not supported detect that and trap here.
+	 * But for now trust that people know what they are doing.
+	 */
+}
+#endif /* NOLIBC_ARCH_HAS_RELOC */
+
+#endif /* _NOLIBC_RELOC_H */
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 4/9] tools/nolibc: m68k: Add relocation support
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
                   ` (2 preceding siblings ...)
  2026-01-31  7:44 ` [RFC PATCH 3/9] tools/nolibc: Add basic ELF self-relocation support for static PIE Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-01-31  7:44 ` [RFC PATCH 5/9] tools/nolibc: x86: Add relocation support for x86_64 Daniel Palmer
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

Add support for handling relocations on m68k.

This also changes the branch to _start_c to be relative.
This might break FLAT binaries so needs to be checked
and probably wrapped in some #ifdef .. magic.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 tools/include/nolibc/arch-m68k.h | 20 +++++++++++++++++++-
 1 file changed, 19 insertions(+), 1 deletion(-)

diff --git a/tools/include/nolibc/arch-m68k.h b/tools/include/nolibc/arch-m68k.h
index 2a4fbada5e79..39df399a1f12 100644
--- a/tools/include/nolibc/arch-m68k.h
+++ b/tools/include/nolibc/arch-m68k.h
@@ -10,8 +10,12 @@
 #ifndef _NOLIBC_ARCH_M68K_H
 #define _NOLIBC_ARCH_M68K_H
 
+#define NOLIBC_ARCH_HAS_RELOC
+#define NOLIBC_ARCH_ELF32
+
 #include "compiler.h"
 #include "crt.h"
+#include "elf.h"
 
 #define _NOLIBC_SYSCALL_CLOBBERLIST "memory"
 
@@ -129,12 +133,26 @@
 })
 
 #ifndef NOLIBC_NO_RUNTIME
+static int __relocate_rela(unsigned long base, Elf32_Rela *entry)
+{
+	switch (ELF32_R_TYPE(entry->r_info)) {
+	case R_68K_RELATIVE:
+		__relocate_rela_relative(base, entry);
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
 void _start(void);
 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
 {
 	__asm__ volatile (
 		"movel %sp, %sp@-\n"
-		"jsr _start_c\n"
+		"lea _start_c(%pc), %a0\n"
+		"jsr (%a0)\n"
 	);
 	__nolibc_entrypoint_epilogue();
 }
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 5/9] tools/nolibc: x86: Add relocation support for x86_64
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
                   ` (3 preceding siblings ...)
  2026-01-31  7:44 ` [RFC PATCH 4/9] tools/nolibc: m68k: Add relocation support Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-02-01 17:56   ` Willy Tarreau
  2026-01-31  7:44 ` [RFC PATCH 6/9] tools/nolibc: riscv: Add relocation support Daniel Palmer
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

Add relocation support for x86, both 32bit and 64bit.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 tools/include/nolibc/arch-x86.h | 35 +++++++++++++++++++++++++++++++++
 1 file changed, 35 insertions(+)

diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h
index f6c43ac5377b..3639c1104e0d 100644
--- a/tools/include/nolibc/arch-x86.h
+++ b/tools/include/nolibc/arch-x86.h
@@ -7,8 +7,17 @@
 #ifndef _NOLIBC_ARCH_X86_H
 #define _NOLIBC_ARCH_X86_H
 
+#define NOLIBC_ARCH_HAS_RELOC
+#if !defined(__x86_64__)
+#define NOLIBC_ARCH_ELF32
+#define NOLIBC_ARCH_ELF_REL
+#elif defined(__x86_64__) && defined(__ILP32__)
+#define NOLIBC_ARCH_ELF32
+#endif
+
 #include "compiler.h"
 #include "crt.h"
+#include "elf.h"
 
 #if !defined(__x86_64__)
 
@@ -158,6 +167,19 @@
 })
 
 #ifndef NOLIBC_NO_RUNTIME
+static int __relocate_rel(unsigned long base, elf_rel *entry)
+{
+	switch (elf_r_type(entry->r_info)) {
+	case R_386_RELATIVE:
+		__relocate_rel_relative(base, entry);
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
 /* startup code */
 /*
  * i386 System V ABI mandates:
@@ -326,6 +348,19 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
 })
 
 #ifndef NOLIBC_NO_RUNTIME
+static int __relocate_rela(unsigned long base, elf_rela *entry)
+{
+	switch (elf_r_type(entry->r_info)) {
+	case R_AMD64_RELATIVE:
+		__relocate_rela_relative(base, entry);
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
 /* startup code */
 /*
  * x86-64 System V ABI mandates:
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 6/9] tools/nolibc: riscv: Add relocation support
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
                   ` (4 preceding siblings ...)
  2026-01-31  7:44 ` [RFC PATCH 5/9] tools/nolibc: x86: Add relocation support for x86_64 Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-01-31  7:44 ` [RFC PATCH 7/9] tools/nolibc: arm: " Daniel Palmer
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

Add relocation support for 32 and 64bit riscv.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 tools/include/nolibc/arch-riscv.h | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index 1c00cacf57e1..76618d4c001d 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -7,6 +7,11 @@
 #ifndef _NOLIBC_ARCH_RISCV_H
 #define _NOLIBC_ARCH_RISCV_H
 
+#if __riscv_xlen == 32
+#define NOLIBC_ARCH_ELF32
+#endif
+#define NOLIBC_ARCH_HAS_RELOC
+
 #include "compiler.h"
 #include "crt.h"
 
@@ -140,6 +145,19 @@
 })
 
 #ifndef NOLIBC_NO_RUNTIME
+static int __relocate_rela(unsigned long base, elf_rela *entry)
+{
+	switch (elf_r_type(entry->r_info)) {
+	case R_RISCV_RELATIVE:
+		__relocate_rela_relative(base, entry);
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
 /* startup code */
 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
 {
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 7/9] tools/nolibc: arm: Add relocation support
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
                   ` (5 preceding siblings ...)
  2026-01-31  7:44 ` [RFC PATCH 6/9] tools/nolibc: riscv: Add relocation support Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-01-31  7:44 ` [RFC PATCH 8/9] selftests/nolibc: Add option for building with -static-pie Daniel Palmer
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

Add relocation support for arm.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 tools/include/nolibc/arch-arm.h | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index 251c42579028..7f69761eeab1 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -7,6 +7,10 @@
 #ifndef _NOLIBC_ARCH_ARM_H
 #define _NOLIBC_ARCH_ARM_H
 
+#define NOLIBC_ARCH_HAS_RELOC
+#define NOLIBC_ARCH_ELF32
+#define NOLIBC_ARCH_ELF_REL
+
 #include "compiler.h"
 #include "crt.h"
 
@@ -185,6 +189,19 @@
 })
 
 #ifndef NOLIBC_NO_RUNTIME
+static int __relocate_rel(unsigned long base, elf_rel *entry)
+{
+	switch (elf_r_type(entry->r_info)) {
+	case R_ARM_RELATIVE:
+		__relocate_rel_relative(base, entry);
+		break;
+	default:
+		return -1;
+	}
+
+	return 0;
+}
+
 /* startup code */
 void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
 {
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 8/9] selftests/nolibc: Add option for building with -static-pie
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
                   ` (6 preceding siblings ...)
  2026-01-31  7:44 ` [RFC PATCH 7/9] tools/nolibc: arm: " Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-01-31  7:44 ` [RFC PATCH 9/9] fs/binfmt_elf_fdpic: Reflect that PIE binaries also work in KConfig help Daniel Palmer
  2026-02-01 18:14 ` [RFC PATCH 0/9] nolibc: Add static-pie support Willy Tarreau
  9 siblings, 0 replies; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

Allow the tests to build with -static-pie instead of -static to
test the self relocation code works.

Note: This doesn't work 100% correctly. For x86_64 I can see the
test binary is static or static-pie depending on if -static or
-static-pie is used but for m68k it's always static and I had
to hack in the workaround.

I have somehow got the tests to seem to produce static PIE
binaries when requested, and regular static ones when not but
its a mess and this can't be used as-is.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 tools/testing/selftests/nolibc/Makefile        |  2 +-
 tools/testing/selftests/nolibc/Makefile.nolibc |  8 ++++----
 tools/testing/selftests/nolibc/run-tests.sh    | 10 +++++++++-
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/tools/testing/selftests/nolibc/Makefile b/tools/testing/selftests/nolibc/Makefile
index 40f5c2908dda..5d5c3231cc19 100644
--- a/tools/testing/selftests/nolibc/Makefile
+++ b/tools/testing/selftests/nolibc/Makefile
@@ -9,7 +9,7 @@ cc-option = $(call __cc-option, $(CC),,$(1),$(2))
 
 include Makefile.include
 
-CFLAGS = -nostdlib -nostdinc -static \
+CFLAGS = -nostdlib -nostdinc \
 	 -isystem $(top_srcdir)/tools/include/nolibc -isystem $(top_srcdir)/usr/include \
 	 $(CFLAGS_NOLIBC_TEST)
 
diff --git a/tools/testing/selftests/nolibc/Makefile.nolibc b/tools/testing/selftests/nolibc/Makefile.nolibc
index f9d43cbdc894..c55f4c17e06d 100644
--- a/tools/testing/selftests/nolibc/Makefile.nolibc
+++ b/tools/testing/selftests/nolibc/Makefile.nolibc
@@ -304,12 +304,12 @@ sysroot/$(ARCH)/include:
 
 ifneq ($(NOLIBC_SYSROOT),0)
 nolibc-test: nolibc-test.c nolibc-test-linkage.c sysroot/$(ARCH)/include
-	$(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
-	  -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include nolibc-test.c nolibc-test-linkage.c $(LIBGCC)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
+	  -nostdlib -nostdinc -Isysroot/$(ARCH)/include nolibc-test.c nolibc-test-linkage.c $(LIBGCC)
 else
 nolibc-test: nolibc-test.c nolibc-test-linkage.c
-	$(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
-	  -nostdlib -static -include $(srctree)/tools/include/nolibc/nolibc.h nolibc-test.c nolibc-test-linkage.c $(LIBGCC)
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \
+	  -nostdlib -include $(srctree)/tools/include/nolibc/nolibc.h nolibc-test.c nolibc-test-linkage.c $(LIBGCC)
 endif
 
 libc-test: nolibc-test.c nolibc-test-linkage.c
diff --git a/tools/testing/selftests/nolibc/run-tests.sh b/tools/testing/selftests/nolibc/run-tests.sh
index 3917cfb8fdc4..12b4774a77d8 100755
--- a/tools/testing/selftests/nolibc/run-tests.sh
+++ b/tools/testing/selftests/nolibc/run-tests.sh
@@ -16,6 +16,7 @@ build_location="$(realpath "${cache_dir}"/nolibc-tests/)"
 perform_download=0
 test_mode=system
 werror=1
+staticpie=0
 llvm=
 all_archs=(
 	i386 x86_64 x32
@@ -31,7 +32,7 @@ all_archs=(
 )
 archs="${all_archs[@]}"
 
-TEMP=$(getopt -o 'j:d:c:b:a:m:pelh' -n "$0" -- "$@")
+TEMP=$(getopt -o 'j:d:c:b:a:m:peslh' -n "$0" -- "$@")
 
 eval set -- "$TEMP"
 unset TEMP
@@ -55,6 +56,7 @@ Options:
  -b [DIR]       Build location (default: ${build_location})
  -m [MODE]      Test mode user/system (default: ${test_mode})
  -e             Disable -Werror
+ -s             Enable static PIE (default: ${staticpie})
  -l             Build with LLVM/clang
 EOF
 }
@@ -85,6 +87,9 @@ while true; do
 		'-e')
 			werror=0
 			shift; continue ;;
+		'-s')
+			staticpie=1
+			shift; continue ;;
 		'-l')
 			llvm=1
 			shift; continue ;;
@@ -171,6 +176,9 @@ test_arch() {
 	if [ "$werror" -ne 0 ]; then
 		CFLAGS_EXTRA="$CFLAGS_EXTRA -Werror -Wl,--fatal-warnings"
 	fi
+	if [ "$staticpie" -ne 0 ]; then
+		CFLAGS_EXTRA="$CFLAGS_EXTRA -ggdb -fPIE -pie -Wl,--no-dynamic-linker -Wl,-ztext -Wl,-zseparate-code"
+	fi
 	MAKE=(make -f Makefile.nolibc -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" LLVM="${llvm}" O="${build_dir}")
 
 	case "$test_mode" in
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* [RFC PATCH 9/9] fs/binfmt_elf_fdpic: Reflect that PIE binaries also work in KConfig help
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
                   ` (7 preceding siblings ...)
  2026-01-31  7:44 ` [RFC PATCH 8/9] selftests/nolibc: Add option for building with -static-pie Daniel Palmer
@ 2026-01-31  7:44 ` Daniel Palmer
  2026-02-01 16:27   ` Thomas Weißschuh
  2026-02-01 18:14 ` [RFC PATCH 0/9] nolibc: Add static-pie support Willy Tarreau
  9 siblings, 1 reply; 19+ messages in thread
From: Daniel Palmer @ 2026-01-31  7:44 UTC (permalink / raw)
  To: linux, w; +Cc: kees, linux-kernel, Daniel Palmer

Since commit 1bde925d2354 ("fs/binfmt_elf_fdpic.c: provide NOMMU loader for regular ELF binaries")
it has been possible to load some normal ELF binaries on nommu but it
wasn't documented in the help.

Since nolibc can generate static-pie binaries that work with this loader
document that normal ELFs can work as long as they are PIE and you have
a linker and that nolibc can also generate static-PIE binaries that
can load without any assitance.

Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
 fs/Kconfig.binfmt | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 1949e25c7741..71573bfd32ac 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -69,6 +69,16 @@ config BINFMT_ELF_FDPIC
 
 	  It is also possible to run FDPIC ELF binaries on MMU linux also.
 
+	  On nommu systems this can also load normal ELF binaries as long as
+	  the binary is linked as PIE. If the binary is not static PIE, does not
+	  include it's own relocation code, this requires a linker like uldso to
+	  be present and set as the interpreter.
+
+	  nolibc included in the kernel source can create static-PIE binaries
+	  by including relocation code and the resulting binaries run on MMU
+	  systems with the normal ELF loader and on nommu systems with this
+	  loader.
+
 config ELFCORE
 	bool
 	help
-- 
2.51.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 1/9] elf: Add relocation types used by nolibc
  2026-01-31  7:44 ` [RFC PATCH 1/9] elf: Add relocation types used by nolibc Daniel Palmer
@ 2026-02-01 16:25   ` Thomas Weißschuh
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Weißschuh @ 2026-02-01 16:25 UTC (permalink / raw)
  To: Daniel Palmer; +Cc: w, kees, linux-kernel

On 2026-01-31 16:44:32+0900, Daniel Palmer wrote:
> nolibc based programs are gaining the ability to relocate themselves
> so that they can support PIE without needing a linker or special
> crt from the toolchain.
> 
> Add the required relocation types.
> 
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
>  include/uapi/linux/elf-r.h | 27 +++++++++++++++++++++++++++
>  include/uapi/linux/elf.h   |  1 +
>  2 files changed, 28 insertions(+)
>  create mode 100644 include/uapi/linux/elf-r.h
> 
> diff --git a/include/uapi/linux/elf-r.h b/include/uapi/linux/elf-r.h
> new file mode 100644
> index 000000000000..a1dce23104a7
> --- /dev/null
> +++ b/include/uapi/linux/elf-r.h
> @@ -0,0 +1,27 @@
> +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
> +#ifndef _LINUX_ELF_R_H
> +#define _LINUX_ELF_R_H
> +
> +/* These constants define various ELF relocation types */
> +#define R_386_RELATIVE		8

This will break the regular kernel build, as these constants are now
defined twice. A proper version will need to move all these constants
from the kernel-internal headers to the UAPI headers.

For the RFC phase this is fine, though.

(...)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 9/9] fs/binfmt_elf_fdpic: Reflect that PIE binaries also work in KConfig help
  2026-01-31  7:44 ` [RFC PATCH 9/9] fs/binfmt_elf_fdpic: Reflect that PIE binaries also work in KConfig help Daniel Palmer
@ 2026-02-01 16:27   ` Thomas Weißschuh
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Weißschuh @ 2026-02-01 16:27 UTC (permalink / raw)
  To: Daniel Palmer; +Cc: w, kees, linux-kernel

On 2026-01-31 16:44:40+0900, Daniel Palmer wrote:
> Since commit 1bde925d2354 ("fs/binfmt_elf_fdpic.c: provide NOMMU loader for regular ELF binaries")
> it has been possible to load some normal ELF binaries on nommu but it
> wasn't documented in the help.
> 
> Since nolibc can generate static-pie binaries that work with this loader
> document that normal ELFs can work as long as they are PIE and you have
> a linker and that nolibc can also generate static-PIE binaries that
> can load without any assitance.
> 
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
>  fs/Kconfig.binfmt | 10 ++++++++++
>  1 file changed, 10 insertions(+)
> 
> diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
> index 1949e25c7741..71573bfd32ac 100644
> --- a/fs/Kconfig.binfmt
> +++ b/fs/Kconfig.binfmt
> @@ -69,6 +69,16 @@ config BINFMT_ELF_FDPIC
>  
>  	  It is also possible to run FDPIC ELF binaries on MMU linux also.
>  
> +	  On nommu systems this can also load normal ELF binaries as long as
> +	  the binary is linked as PIE. If the binary is not static PIE, does not
> +	  include it's own relocation code, this requires a linker like uldso to
> +	  be present and set as the interpreter.

Something like this can be split out of this series and submitted standalone.

> +
> +	  nolibc included in the kernel source can create static-PIE binaries
> +	  by including relocation code and the resulting binaries run on MMU
> +	  systems with the normal ELF loader and on nommu systems with this
> +	  loader.

I don't think this paragraph should be here.
Maybe we can add the information to the nolibc documentation instead.

> +
>  config ELFCORE
>  	bool
>  	help
> -- 
> 2.51.0
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 2/9] tools/nolibc: crt: Split _start_c() into stack-only and normal part
  2026-01-31  7:44 ` [RFC PATCH 2/9] tools/nolibc: crt: Split _start_c() into stack-only and normal part Daniel Palmer
@ 2026-02-01 16:33   ` Thomas Weißschuh
  0 siblings, 0 replies; 19+ messages in thread
From: Thomas Weißschuh @ 2026-02-01 16:33 UTC (permalink / raw)
  To: Daniel Palmer; +Cc: w, kees, linux-kernel

On 2026-01-31 16:44:33+0900, Daniel Palmer wrote:
> To prepare for nolibc programs being able to relocate themselves
> we need to split _start_c() into two parts:
> 
> - One part that only uses the stack so there are no accesses via
>   the GOT etc that isn't setup yet. Note that on m68k at least
>   this also means forcing the stackprotector off because accessing
>   the stack protector canary is done via the GOT.
> 
> - Another part that is called after we have done relocation so it
>   is safe to access global variables etc that might use the GOT etc.
> 
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
>  tools/include/nolibc/crt.h | 57 +++++++++++++++++++++++---------------
>  1 file changed, 35 insertions(+), 22 deletions(-)
> 
> diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> index d9262998dae9..899062c00fb7 100644
> --- a/tools/include/nolibc/crt.h
> +++ b/tools/include/nolibc/crt.h
> @@ -27,26 +27,51 @@ extern void (*const __init_array_end[])(int, char **, char**) __attribute__((wea
>  extern void (*const __fini_array_start[])(void) __attribute__((weak));
>  extern void (*const __fini_array_end[])(void) __attribute__((weak));
>  
> -void _start_c(long *sp);
> -__attribute__((weak,used))
> +void __start_c(long argc, char **argv, char **envp, const unsigned long *auxv);
> +__attribute__((weak, used))

We now have an additional never-inlined, global function.
This should stay inlinable in the regular case.

>  #if __nolibc_has_feature(undefined_behavior_sanitizer)
>  	__attribute__((no_sanitize("function")))
>  #endif
> -void _start_c(long *sp)
> +void __no_stack_protector __start_c(long argc, char **argv, char **envp, const unsigned long *auxv)

Please some better naming.

_start_c_global_data() or something.

>  {
> -	long argc;
> -	char **argv;
> -	char **envp;
> -	int exitcode;
>  	void (* const *ctor_func)(int, char **, char **);
>  	void (* const *dtor_func)(void);
> -	const unsigned long *auxv;
>  	/* silence potential warning: conflicting types for 'main' */
>  	int _nolibc_main(int, char **, char **) __asm__ ("main");
> +	int exitcode;
>  
>  	/* initialize stack protector */
>  	__stack_chk_init();
>  
> +	environ = envp;
> +	_auxv = auxv;
> +
> +	for (ctor_func = __preinit_array_start; ctor_func < __preinit_array_end; ctor_func++)
> +		(*ctor_func)(argc, argv, envp);
> +	for (ctor_func = __init_array_start; ctor_func < __init_array_end; ctor_func++)
> +		(*ctor_func)(argc, argv, envp);
> +
> +	/* go to application */
> +	exitcode = _nolibc_main(argc, argv, envp);
> +
> +	for (dtor_func = __fini_array_end; dtor_func > __fini_array_start;)
> +		(*--dtor_func)();
> +
> +	exit(exitcode);
> +}
> +
> +void _start_c(long *sp);
> +__attribute__((weak, used))
> +#if __nolibc_has_feature(undefined_behavior_sanitizer)
> +	__attribute__((no_sanitize("function")))
> +#endif

Now that this is repeated, it should be behind a #define.

> +void __no_stack_protector _start_c(long *sp)
> +{

(...)

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 3/9] tools/nolibc: Add basic ELF self-relocation support for static PIE
  2026-01-31  7:44 ` [RFC PATCH 3/9] tools/nolibc: Add basic ELF self-relocation support for static PIE Daniel Palmer
@ 2026-02-01 16:42   ` Thomas Weißschuh
  2026-02-01 21:54     ` Daniel Palmer
  0 siblings, 1 reply; 19+ messages in thread
From: Thomas Weißschuh @ 2026-02-01 16:42 UTC (permalink / raw)
  To: Daniel Palmer; +Cc: w, kees, linux-kernel

On 2026-01-31 16:44:34+0900, Daniel Palmer wrote:
> Currently nolibc programs cannot be compiled with -static-pie.
> Which is basically no shared libraries, no interpreter, but contain
> relocation information in the ELF to allow the program to be fixed
> up to run at the address that the kernel loaded it to.
> 
> There might be use cases for static PIE but mine is for nommu.
> The ELF FDPIC loader can actually load normal ELFs is long as they
> can be relocated.
> 
> This very basic implementation does the following:
> 
> - Works out if we are PIE and need to be relocated. ELF type == ET_DYN
> - Works out if we are static PIE, have no interpreter, and need to
>   relocate ourselves.
> - Calculates the base address using the location of the program
>   headers. This is probably not correct.
> - Finds the ELF relocation data.
> - Calls an arch specific function to handle each of the relocations.
> 
> Note that from testing a lot of archs don't produce static PIE
> binaries with the -static-pie option and you need to compile with
> -pie -Wl,--no-dynamic-linker to get a static PIE binary.
> 
> Currently REL and RELA formats are supported.
> 
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
>  tools/include/nolibc/Makefile |   1 +
>  tools/include/nolibc/crt.h    |   7 +
>  tools/include/nolibc/reloc.h  | 240 ++++++++++++++++++++++++++++++++++
>  3 files changed, 248 insertions(+)
>  create mode 100644 tools/include/nolibc/reloc.h
> 
> diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile
> index 8118e22844f1..2b968a097854 100644
> --- a/tools/include/nolibc/Makefile
> +++ b/tools/include/nolibc/Makefile
> @@ -38,6 +38,7 @@ all_files := \
>  		math.h \
>  		nolibc.h \
>  		poll.h \
> +		reloc.h \
>  		sched.h \
>  		signal.h \
>  		stackprotector.h \
> diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> index 899062c00fb7..3c1c8d738ac7 100644
> --- a/tools/include/nolibc/crt.h
> +++ b/tools/include/nolibc/crt.h
> @@ -10,6 +10,7 @@
>  #ifndef NOLIBC_NO_RUNTIME
>  
>  #include "compiler.h"
> +#include "reloc.h"
>  
>  char **environ __attribute__((weak));
>  const unsigned long *_auxv __attribute__((weak));
> @@ -100,6 +101,12 @@ void __no_stack_protector _start_c(long *sp)
>  	for (auxv = (void *)envp; *auxv++;)
>  		;
>  
> +	/*
> +	 * Do relocation if required and supported, this must happen before any
> +	 * global variables are updated or used.
> +	 */
> +	_relocate(auxv);
> +
>  	__start_c(argc, argv, envp, auxv);
>  }
>  
> diff --git a/tools/include/nolibc/reloc.h b/tools/include/nolibc/reloc.h
> new file mode 100644
> index 000000000000..98c42af6f845
> --- /dev/null
> +++ b/tools/include/nolibc/reloc.h
> @@ -0,0 +1,240 @@
> +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */
> +/*
> + * Self relocation support for NOLIBC
> + * Copyright (C) 2026 Daniel Palmer<daniel@thingy.jp>
> + *
> + * This allows a PIE compiled nolibc binary relocate itself
> + * instead of relying on a dynamic linker. So called "static PIE".


> + * With some care binaries produced with this relocation code
> + * can run via the FDPIC ELF loader on nommu systems.
> + *
> + * I am not expert in all of the different options for GCC but
> + * this works for me for x86:
> + * gcc -nostdlib -fpie -Os -include <path to nolibc.h> \
> + * -static-pie -o helloworld helloworld.c
> + *
> + * For some targets -static-pie doesn't work but setting PIE and
> + * then disabling the linker results in a static-pie:
> + * gcc -nostdlib -fpie -Os -include <path to nolibc.h> \
> + * -Wl,--no-dynamic-linker -pie -o helloworld helloworld.c

These last few paragraphs don't belong here IMO.

> + */
> +
> +#ifndef _NOLIBC_RELOC_H
> +#define _NOLIBC_RELOC_H
> +
> +#ifdef NOLIBC_ARCH_HAS_RELOC

Internal symbols which are not meant to be provided by the user should
use an underscore prefix.

> +#include "elf.h"
> +#include <linux/auxvec.h>
> +
> +#ifdef NOLIBC_ARCH_ELF32
> +#define elf_ehdr Elf32_Ehdr
> +#define elf_phdr Elf32_Phdr
> +/* 32bit ARM, x86 uses REL instead of RELA */
> +#ifdef NOLIBC_ARCH_ELF_REL
> +#define elf_rel  Elf32_Rel
> +#else
> +#define elf_rela Elf32_Rela
> +#endif
> +#define elf_dyn  Elf32_Dyn
> +#define elf_addr Elf32_Addr
> +#define elf_r_type(_x) ELF32_R_TYPE(_x)
> +#else
> +#define elf_ehdr Elf64_Ehdr
> +#define elf_phdr Elf64_Phdr
> +#define elf_dyn  Elf64_Dyn
> +#define elf_rela Elf64_Rela
> +#define elf_addr Elf64_Addr
> +#define elf_r_type(_x) ELF64_R_TYPE(_x)
> +#endif

These symbols are polluting the global namespace.
They should also use some underscore and 'nolibc' prefix.

> +
> +#ifdef NOLIBC_ARCH_ELF_REL
> +/*
> + * Your arch needs to provide this to actually handle doing each of the
> + * relocations if it uses the REL format.
> + */
> +static int __relocate_rel(unsigned long base, elf_rel *entry);
> +
> +/* Generic implementation of R_x_RELATIVE for REL */
> +#define __relocate_rel_relative(_base, _entry)			\
> +	do {							\
> +		elf_addr *_addr;				\
> +		int addend;					\
> +								\
> +		_addr = (elf_addr *)(_base + _entry->r_offset);	\
> +		addend = *_addr;				\
> +		*_addr = _base + addend;			\
> +	} while (0)
> +
> +static int __relocate(unsigned long base,
> +		      unsigned long rel_off,
> +		      unsigned long rel_count)
> +{
> +	elf_rel *rel = (elf_rel *)(base + rel_off);
> +	unsigned long i;
> +
> +	for (i = 0; i < rel_count; i++) {
> +		if (__relocate_rel(base, &rel[i]))
> +			return -1;
> +	}
> +
> +	return 0;
> +}
> +#else
> +/*
> + * Your arch needs to provide this to actually handle doing each of the
> + * relocations if it uses the RELA format.
> + */
> +static int __relocate_rela(unsigned long base, elf_rela *entry);
> +
> +/* Generic implementation of R_x_RELATIVE for RELA */
> +#define __relocate_rela_relative(_base, _entry)			\
> +	do {							\
> +		elf_addr *_addr;				\
> +								\
> +		_addr = (elf_addr *)(_base + _entry->r_offset);	\
> +		*_addr = (elf_addr) (_base + _entry->r_addend);	\
> +	} while (0)

Does this need to be a macro?

> +
> +static int __relocate(unsigned long base,
> +		      unsigned long rela_off,
> +		      unsigned long rela_count)
> +{
> +	elf_rela *rela = (elf_rela *)(base + rela_off);
> +	unsigned long i;
> +
> +	for (i = 0; i < rela_count; i++) {
> +		if (__relocate_rela(base, &rela[i]))
> +			return -1;
> +	}
> +
> +	return 0;
> +}
> +#endif
> +
> +static void _relocate(const unsigned long *auxv)
> +{
> +	unsigned long rel_rela_count = 0;
> +	unsigned long rel_rela_off = 0;
> +	unsigned long phdr_addr = 0;
> +	unsigned long phdr_num = 0;
> +	unsigned long phdr_sz = 0;
> +	elf_phdr *phdr_dyn = NULL;
> +	unsigned long base;
> +	unsigned long i;
> +	int remaining;
> +	elf_ehdr *ehdr;
> +	elf_dyn *dyn;
> +
> +	for (remaining = 3; remaining; ) {
> +		if (!auxv[0] && !auxv[1])
> +			break;
> +
> +		switch (auxv[0]) {
> +		case AT_NOTELF:
> +			return;
> +
> +		case AT_PHDR:
> +			phdr_addr = auxv[1];
> +			remaining--;
> +			break;
> +
> +		case AT_PHNUM:
> +			phdr_num = auxv[1];
> +			remaining--;
> +			break;
> +
> +		/*
> +		 * Not sure if this is even needed, should match
> +		 * the size of the program header type?
> +		 */
> +		case AT_PHENT:
> +			phdr_sz = auxv[1];
> +			remaining--;
> +			break;
> +		}

I think we either ignore this or abort on any mismatch.

> +
> +		auxv += 2;
> +	}
> +
> +	if (remaining)
> +		goto failed;
> +
> +	/*
> +	 * Everything I could find said that the way to find the base for relocation
> +	 * should be done by searching for the first PT_LOAD and then using the ofset
> +	 * of that against the adressed of the program headers. So FIXME.
> +	 */
> +	base = phdr_addr - sizeof(elf_ehdr);

What was wrong with AT_BASE?

> +
> +	/* Check that we are PIE */
> +	ehdr = (elf_ehdr *) base;
> +	if (ehdr->e_type != ET_DYN)
> +		return;
> +
> +	for (i = 0, remaining = 1; (i < phdr_num) && remaining; i++) {
> +		elf_phdr *phdr = (elf_phdr *)(phdr_addr + (phdr_sz * i));
> +
> +		switch (phdr->p_type) {
> +		case PT_INTERP:
> +			/* Interp was set, we were relocated already?, return */
> +			return;
> +		case PT_DYNAMIC:
> +			phdr_dyn = phdr;
> +			remaining--;
> +			break;
> +		}
> +	}
> +
> +	if (!phdr_dyn)
> +		goto failed;
> +
> +	dyn = (elf_dyn *)(base + phdr_dyn->p_offset);
> +	for (; dyn->d_tag != DT_NULL; dyn++) {
> +		switch (dyn->d_tag) {
> +#ifdef NOLIBC_ARCH_ELF_REL
> +		case DT_REL:
> +			rel_rela_off = dyn->d_un.d_ptr;
> +			break;
> +		case DT_RELCOUNT:
> +			rel_rela_count = dyn->d_un.d_val;
> +			break;
> +		}
> +#else
> +		case DT_RELA:
> +			rel_rela_off = dyn->d_un.d_ptr;
> +			break;
> +		case DT_RELACOUNT:
> +			rel_rela_count = dyn->d_un.d_val;
> +			break;
> +		}
> +#endif
> +
> +		/* Got what we came for, exit loop */
> +		if (rel_rela_off && rel_rela_count)
> +			break;
> +	}
> +
> +	if (!rel_rela_off || !rel_rela_count)
> +		goto failed;
> +
> +	if (__relocate(base, rel_rela_off, rel_rela_count))
> +		goto failed;
> +
> +	return;
> +
> +failed:
> +	__builtin_trap();
> +}
> +#else
> +static void _relocate(const unsigned long *auxv __attribute__((unused)))
> +{
> +	/*
> +	 * Maybe if you build a program that needs relocation
> +	 * but it's not supported detect that and trap here.
> +	 * But for now trust that people know what they are doing.
> +	 */
> +}
> +#endif /* NOLIBC_ARCH_HAS_RELOC */
> +
> +#endif /* _NOLIBC_RELOC_H */
> -- 
> 2.51.0
> 

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 5/9] tools/nolibc: x86: Add relocation support for x86_64
  2026-01-31  7:44 ` [RFC PATCH 5/9] tools/nolibc: x86: Add relocation support for x86_64 Daniel Palmer
@ 2026-02-01 17:56   ` Willy Tarreau
  0 siblings, 0 replies; 19+ messages in thread
From: Willy Tarreau @ 2026-02-01 17:56 UTC (permalink / raw)
  To: Daniel Palmer; +Cc: linux, kees, linux-kernel

Hi Daniel,

On Sat, Jan 31, 2026 at 04:44:36PM +0900, Daniel Palmer wrote:
> Add relocation support for x86, both 32bit and 64bit.
> 
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
>  tools/include/nolibc/arch-x86.h | 35 +++++++++++++++++++++++++++++++++
>  1 file changed, 35 insertions(+)
> 
> diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h
> index f6c43ac5377b..3639c1104e0d 100644
> --- a/tools/include/nolibc/arch-x86.h
> +++ b/tools/include/nolibc/arch-x86.h
> @@ -7,8 +7,17 @@
>  #ifndef _NOLIBC_ARCH_X86_H
>  #define _NOLIBC_ARCH_X86_H
>  
> +#define NOLIBC_ARCH_HAS_RELOC
> +#if !defined(__x86_64__)
> +#define NOLIBC_ARCH_ELF32
> +#define NOLIBC_ARCH_ELF_REL
> +#elif defined(__x86_64__) && defined(__ILP32__)
> +#define NOLIBC_ARCH_ELF32
> +#endif
> +
>  #include "compiler.h"
>  #include "crt.h"
> +#include "elf.h"
>  
>  #if !defined(__x86_64__)
>  
> @@ -158,6 +167,19 @@
>  })
>  
>  #ifndef NOLIBC_NO_RUNTIME
> +static int __relocate_rel(unsigned long base, elf_rel *entry)
> +{
> +	switch (elf_r_type(entry->r_info)) {
> +	case R_386_RELATIVE:
> +		__relocate_rel_relative(base, entry);
> +		break;
> +	default:
> +		return -1;
> +	}
> +
> +	return 0;
> +}
> +
>  /* startup code */
>  /*
>   * i386 System V ABI mandates:
> @@ -326,6 +348,19 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
>  })
>  
>  #ifndef NOLIBC_NO_RUNTIME
> +static int __relocate_rela(unsigned long base, elf_rela *entry)
> +{
> +	switch (elf_r_type(entry->r_info)) {
> +	case R_AMD64_RELATIVE:

This needs to be conditioned to the definition of this macro, because
now building with the patched nolibc against older UAPI headers just
breaks the build:

../../../include/nolibc/arch-x86.h: In function '__relocate_rela':
../../../include/nolibc/arch-x86.h:354:14: error: 'R_AMD64_RELATIVE' undeclared (first use in this function)
  354 |         case R_AMD64_RELATIVE:
      |              ^~~~~~~~~~~~~~~~

We always take care of keeping support for still maintained kernels, so
right now it's important that uapi headers from 5.10 continue to produce
code that builds and works (which is still the case before the patch).

Willy

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 0/9] nolibc: Add static-pie support
  2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
                   ` (8 preceding siblings ...)
  2026-01-31  7:44 ` [RFC PATCH 9/9] fs/binfmt_elf_fdpic: Reflect that PIE binaries also work in KConfig help Daniel Palmer
@ 2026-02-01 18:14 ` Willy Tarreau
  2026-02-01 21:45   ` Daniel Palmer
  9 siblings, 1 reply; 19+ messages in thread
From: Willy Tarreau @ 2026-02-01 18:14 UTC (permalink / raw)
  To: Daniel Palmer; +Cc: linux, kees, linux-kernel

On Sat, Jan 31, 2026 at 04:44:31PM +0900, Daniel Palmer wrote:
> For more background see:
> https://lore.kernel.org/lkml/20260116122812.2421621-1-daniel@thingy.jp/
> 
> Basically I am trying to run normal ELF binaries created with
> nolibc on nommu (m68k, 68000). To make this work without an external
> linker nolibc needs code to do the relocation.
> 
> The following is my attempt at doing this by hacking just enough
> together that static-pie binaries work on a few archs.
> The ones that work have a patch in this series.
> 
> Answers to questions you might have:
> Q: Don't we need to handle more relocation types?
> A: Maybe, everything exception sparc only had R_x_RELATIVE in
>    the nolibc test binary. sparc emits R_SPARC_NONE as well.
> 
> Q: Don't we need to make some sections writable for this to
>    work.
> A: Maybe, I tried to get most of the supported archs working.
>    The only one that had relocations on a non-writable section
>    was arm64 and I think I can fix it so it doesn't need that.
> 
> Q: Why can't you just pass -static-pie to gcc?
> A: Only x86 seemed to actually produce static PIE binaries doing
>    that. Everything else produced normal static ones. Maybe this
>    is a compiler version thing?
> 
> There are probably things I'm missing, things I have done totally
> wrong. Please feel free to grill me.

I'm noticing a significant size increase with this change, and I'm
not sure all of it is well justified:

  $ size nolibc-test-*
     text    data     bss     dec     hex filename
    43300     120     112   43532    aa0c nolibc-test-6.19-rc7
    44524     120     112   44756    aed4 nolibc-test-daniel
  
    => +1.2 kB

Even a trivial "return 0;" program:

  $ size ret0-*      
     text    data     bss     dec     hex filename
    309      24      24     357     165 ret0-6.19-rc7
    642      24      24     690     2b2 ret0-daniel

    => +333 B

The difference I'm seeing is here:

  $ diff -u ret0*size
  --- ret0-6.19-rc7.size  2026-02-01 19:04:33.918536545 +0100
  +++ ret0-daniel.size    2026-02-01 19:04:40.914761767 +0100
  @@ -16,4 +16,5 @@
   0000000000000011 W raise
   0000000000000012 W abort
   0000000000000023 W memmove
  -0000000000000098 W _start_c
  +0000000000000086 W __start_c
  +000000000000015f W _start_c

The delta is indeed 333 bytes.

Is there anything we could detect at build time to detect that we want to
go the heavy way ? Maybe we should only condition that code to __PIE__ ?
There's nothing critical, it's really about having an open discussion on
this, because we're trying to keep the minimal binaries small, and here
we're just doubling the size of the smallest ones all the time.

Thanks!
Willy

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 0/9] nolibc: Add static-pie support
  2026-02-01 18:14 ` [RFC PATCH 0/9] nolibc: Add static-pie support Willy Tarreau
@ 2026-02-01 21:45   ` Daniel Palmer
  2026-02-01 21:49     ` Willy Tarreau
  0 siblings, 1 reply; 19+ messages in thread
From: Daniel Palmer @ 2026-02-01 21:45 UTC (permalink / raw)
  To: Willy Tarreau; +Cc: linux, kees, linux-kernel

Hi Willy,

On Mon, 2 Feb 2026 at 03:14, Willy Tarreau <w@1wt.eu> wrote:
>   $ diff -u ret0*size
>   --- ret0-6.19-rc7.size  2026-02-01 19:04:33.918536545 +0100
>   +++ ret0-daniel.size    2026-02-01 19:04:40.914761767 +0100
>   @@ -16,4 +16,5 @@
>    0000000000000011 W raise
>    0000000000000012 W abort
>    0000000000000023 W memmove
>   -0000000000000098 W _start_c
>   +0000000000000086 W __start_c
>   +000000000000015f W _start_c
>
> The delta is indeed 333 bytes.
>
> Is there anything we could detect at build time to detect that we want to
> go the heavy way ? Maybe we should only condition that code to __PIE__ ?
> There's nothing critical, it's really about having an open discussion on
> this, because we're trying to keep the minimal binaries small, and here
> we're just doubling the size of the smallest ones all the time.
>
> Thanks!
> Willy

Thank you for the feedback. I'll work out a way of hiding all of the
new code unless it's needed.
I think there might still be some increase in size from splitting
_start_c() into two parts though.

Thanks,

Daniel

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 0/9] nolibc: Add static-pie support
  2026-02-01 21:45   ` Daniel Palmer
@ 2026-02-01 21:49     ` Willy Tarreau
  0 siblings, 0 replies; 19+ messages in thread
From: Willy Tarreau @ 2026-02-01 21:49 UTC (permalink / raw)
  To: Daniel Palmer; +Cc: linux, kees, linux-kernel

On Mon, Feb 02, 2026 at 06:45:40AM +0900, Daniel Palmer wrote:
> Hi Willy,
> 
> On Mon, 2 Feb 2026 at 03:14, Willy Tarreau <w@1wt.eu> wrote:
> >   $ diff -u ret0*size
> >   --- ret0-6.19-rc7.size  2026-02-01 19:04:33.918536545 +0100
> >   +++ ret0-daniel.size    2026-02-01 19:04:40.914761767 +0100
> >   @@ -16,4 +16,5 @@
> >    0000000000000011 W raise
> >    0000000000000012 W abort
> >    0000000000000023 W memmove
> >   -0000000000000098 W _start_c
> >   +0000000000000086 W __start_c
> >   +000000000000015f W _start_c
> >
> > The delta is indeed 333 bytes.
> >
> > Is there anything we could detect at build time to detect that we want to
> > go the heavy way ? Maybe we should only condition that code to __PIE__ ?
> > There's nothing critical, it's really about having an open discussion on
> > this, because we're trying to keep the minimal binaries small, and here
> > we're just doubling the size of the smallest ones all the time.
> >
> > Thanks!
> > Willy
> 
> Thank you for the feedback. I'll work out a way of hiding all of the
> new code unless it's needed.
> I think there might still be some increase in size from splitting
> _start_c() into two parts though.

Yes but that's expected. We can spend a few bytes here and there for the
good cause, it's just that here there's an opportunity to avoid most of
them when not needed.

Thanks,
Willy

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: [RFC PATCH 3/9] tools/nolibc: Add basic ELF self-relocation support for static PIE
  2026-02-01 16:42   ` Thomas Weißschuh
@ 2026-02-01 21:54     ` Daniel Palmer
  0 siblings, 0 replies; 19+ messages in thread
From: Daniel Palmer @ 2026-02-01 21:54 UTC (permalink / raw)
  To: Thomas Weißschuh; +Cc: w, kees, linux-kernel

Hi Thomas,

On Mon, 2 Feb 2026 at 01:42, Thomas Weißschuh <linux@weissschuh.net> wrote:

> > +     /*
> > +      * Everything I could find said that the way to find the base for relocation
> > +      * should be done by searching for the first PT_LOAD and then using the ofset
> > +      * of that against the adressed of the program headers. So FIXME.
> > +      */
> > +     base = phdr_addr - sizeof(elf_ehdr);
>
> What was wrong with AT_BASE?

Apparently AT_BASE is the base of the interpreter
(https://man7.org/linux/man-pages/man3/getauxval.3.html).
I did try it and from what I remember it was 0 on m68k and x86. For
sparc and ppc there seems to be an issue with the address of the
dynamic section calculated from base so on those machines the current
way seems to be wrong either way.

Thank you for all of the other comments. I'll fix those up.

Cheers,

Daniel

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2026-02-01 21:55 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-31  7:44 [RFC PATCH 0/9] nolibc: Add static-pie support Daniel Palmer
2026-01-31  7:44 ` [RFC PATCH 1/9] elf: Add relocation types used by nolibc Daniel Palmer
2026-02-01 16:25   ` Thomas Weißschuh
2026-01-31  7:44 ` [RFC PATCH 2/9] tools/nolibc: crt: Split _start_c() into stack-only and normal part Daniel Palmer
2026-02-01 16:33   ` Thomas Weißschuh
2026-01-31  7:44 ` [RFC PATCH 3/9] tools/nolibc: Add basic ELF self-relocation support for static PIE Daniel Palmer
2026-02-01 16:42   ` Thomas Weißschuh
2026-02-01 21:54     ` Daniel Palmer
2026-01-31  7:44 ` [RFC PATCH 4/9] tools/nolibc: m68k: Add relocation support Daniel Palmer
2026-01-31  7:44 ` [RFC PATCH 5/9] tools/nolibc: x86: Add relocation support for x86_64 Daniel Palmer
2026-02-01 17:56   ` Willy Tarreau
2026-01-31  7:44 ` [RFC PATCH 6/9] tools/nolibc: riscv: Add relocation support Daniel Palmer
2026-01-31  7:44 ` [RFC PATCH 7/9] tools/nolibc: arm: " Daniel Palmer
2026-01-31  7:44 ` [RFC PATCH 8/9] selftests/nolibc: Add option for building with -static-pie Daniel Palmer
2026-01-31  7:44 ` [RFC PATCH 9/9] fs/binfmt_elf_fdpic: Reflect that PIE binaries also work in KConfig help Daniel Palmer
2026-02-01 16:27   ` Thomas Weißschuh
2026-02-01 18:14 ` [RFC PATCH 0/9] nolibc: Add static-pie support Willy Tarreau
2026-02-01 21:45   ` Daniel Palmer
2026-02-01 21:49     ` Willy Tarreau

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox