* [RFC PATCH v2 00/10] nolibc: Add static-pie support
@ 2026-02-04 12:45 Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc Daniel Palmer
` (10 more replies)
0 siblings, 11 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: linux-kernel, Daniel Palmer
v2:
- This is still RFC quality
- I have gotten a few more archs to work (not crash in nolibc-test) so I have added them
to show the that the arch specific parts are pretty small.
- This should now only add this extra code if NOLIBC_WANT_RELOC is defined, which happens
automatically if you compile with -fpie. Should address Willy's concern with the size
blowing up for even binaries that don't need this.
Size difference on ppc64 is massive, I guess PIC code is big there.
static:
$ file nolibc-test
nolibc-test: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, Power ELF V1 ABI, version 1 (SYSV), statically linked, not stripped
$ size nolibc-test
text data bss dec hex filename
59560 3240 104 62904 f5b8 nolibc-test
static pie:
$ file nolibc-test
nolibc-test: ELF 64-bit MSB pie executable, 64-bit PowerPC or cisco 7500, Power ELF V1 ABI, version 1 (SYSV), static-pie linked, with debug_info, not stripped
$ size nolibc-test
text data bss dec hex filename
67801 3656 104 71561 11789 nolibc-test
- Each of the archs checks that the relocations they need (just the one at the moment) is defined
before defining the relocation defines. So this shouldn't break with older UAPI headers.
- I think maybe you might want to set NOLIBC_WANT_RELOC even if __pie__ is not defined,
maybe for testing? So I didn't make it _NOLIBC_WANT_RELOC.
- I was worried some archs didn't work because calling the relocation functions was
causing things like accessing the stack canary before it was accessible. So I added
__inline__ to all of the relocation functions to force them to get inlined into _start_c().
This might be too much. checkpatch certainly hates it.
- I think I addressed most of Thomas' code style comments, prefixing etc. Maybe added some new problems :)
- I cleaned up the REL/RELA differences a bit more so the lines of code has dropped a
bit in reloc.h.
- I fixed working out where the dynamic section is, this fixed SuperH and PPC. I suspect
I can get all of the others except maybe mips working now.
- new elf UAPI header for the relocation types is still wrong, script to run the
self-tests is still wonky.
Thanks in advance,
Daniel
v1: https://lore.kernel.org/lkml/20260131074440.732588-1-daniel@thingy.jp/
v0: https://lore.kernel.org/lkml/20260116122812.2421621-1-daniel@thingy.jp/
Daniel Palmer (10):
elf: Add relocation types used by nolibc
tools/nolibc: crt: Split _start_c() into stack-only and normal parts
tools/nolibc: Add basic ELF self-relocation support for static PIE
tools/nolibc: m68k: Add relocation support
tools/nolibc: x86: Add relocation support
tools/nolibc: riscv: Add relocation support
tools/nolibc: arm: Add relocation support
tools/nolibc: sh: Add relocation support
tools/nolibc: ppc: Add relocation support
selftests/nolibc: Add option for building with -static-pie
include/uapi/linux/elf-r.h | 27 +++
include/uapi/linux/elf.h | 1 +
tools/include/nolibc/Makefile | 1 +
tools/include/nolibc/arch-arm.h | 25 ++
tools/include/nolibc/arch-m68k.h | 27 ++-
tools/include/nolibc/arch-powerpc.h | 24 ++
tools/include/nolibc/arch-riscv.h | 26 ++
tools/include/nolibc/arch-sh.h | 24 ++
tools/include/nolibc/arch-x86.h | 53 +++++
tools/include/nolibc/compiler.h | 6 +
tools/include/nolibc/crt.h | 62 +++--
tools/include/nolibc/reloc.h | 224 ++++++++++++++++++
tools/testing/selftests/nolibc/Makefile | 2 +-
.../testing/selftests/nolibc/Makefile.nolibc | 8 +-
tools/testing/selftests/nolibc/run-tests.sh | 10 +-
15 files changed, 489 insertions(+), 31 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] 22+ messages in thread
* [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-07 15:35 ` Willy Tarreau
2026-02-16 20:33 ` Thomas Weißschuh
2026-02-04 12:45 ` [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts Daniel Palmer
` (9 subsequent siblings)
10 siblings, 2 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: 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] 22+ messages in thread
* [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-07 15:45 ` Willy Tarreau
2026-02-16 20:42 ` Thomas Weißschuh
2026-02-04 12:45 ` [RFC PATCH v2 03/10] tools/nolibc: Add basic ELF self-relocation support for static PIE Daniel Palmer
` (8 subsequent siblings)
10 siblings, 2 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: 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/compiler.h | 6 ++++
tools/include/nolibc/crt.h | 57 ++++++++++++++++++---------------
2 files changed, 38 insertions(+), 25 deletions(-)
diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compiler.h
index 87090bbc53e0..3f403e54e4f4 100644
--- a/tools/include/nolibc/compiler.h
+++ b/tools/include/nolibc/compiler.h
@@ -47,4 +47,10 @@
# define __nolibc_fallthrough do { } while (0)
#endif /* __nolibc_has_attribute(fallthrough) */
+#if __nolibc_has_feature(undefined_behavior_sanitizer)
+# define __no_sanitize __attribute__((no_sanitize("function")))
+#else
+# define __no_sanitize
+#endif
+
#endif /* _NOLIBC_COMPILER_H */
diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index d9262998dae9..fab042f1ff62 100644
--- a/tools/include/nolibc/crt.h
+++ b/tools/include/nolibc/crt.h
@@ -27,26 +27,45 @@ 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))
-#if __nolibc_has_feature(undefined_behavior_sanitizer)
- __attribute__((no_sanitize("function")))
-#endif
-void _start_c(long *sp)
+void _start_c_global_data(long argc, char **argv, char **envp, const unsigned long *auxv);
+__attribute__((weak, used))
+void __no_sanitize __no_stack_protector _start_c_global_data(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))
+void __no_sanitize __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 +88,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_global_data(argc, argv, envp, auxv);
}
#endif /* NOLIBC_NO_RUNTIME */
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC PATCH v2 03/10] tools/nolibc: Add basic ELF self-relocation support for static PIE
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-07 15:49 ` Willy Tarreau
2026-02-04 12:45 ` [RFC PATCH v2 04/10] tools/nolibc: m68k: Add relocation support Daniel Palmer
` (7 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: 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 other 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 ELF program header address
given to us by the kernel and the size of the ELF header that
should be directly above.
- 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 | 224 ++++++++++++++++++++++++++++++++++
3 files changed, 232 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 fab042f1ff62..4b5be276b83b 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));
@@ -94,6 +95,12 @@ void __no_sanitize __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_global_data(argc, argv, envp, auxv);
}
diff --git a/tools/include/nolibc/reloc.h b/tools/include/nolibc/reloc.h
new file mode 100644
index 000000000000..aead8cc680f5
--- /dev/null
+++ b/tools/include/nolibc/reloc.h
@@ -0,0 +1,224 @@
+/* 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.
+ */
+
+#ifndef _NOLIBC_RELOC_H
+#define _NOLIBC_RELOC_H
+
+/*
+ * If NOLIBC_WANT_RELOC is not defined decide based on the
+ * compiler defining __pie__ or not.
+ */
+#ifndef NOLIBC_WANT_RELOC
+#ifdef __pie__
+#define NOLIBC_WANT_RELOC
+#endif
+#endif
+
+#ifdef NOLIBC_WANT_RELOC
+#ifndef _NOLIBC_ARCH_HAS_RELOC
+#error "Relocation requested but arch does not support it"
+#endif
+
+#include <linux/auxvec.h>
+#include "elf.h"
+
+#ifdef _NOLIBC_ARCH_ELF32
+#define _nolibc_elf_ehdr Elf32_Ehdr
+#define _nolibc_elf_phdr Elf32_Phdr
+/* 32bit ARM, x86 uses REL instead of RELA */
+#ifdef _NOLIBC_ARCH_ELF_REL
+#define _nolibc_elf_rel Elf32_Rel
+#else
+#define _nolibc_elf_rela Elf32_Rela
+#endif
+#define _nolibc_elf_dyn Elf32_Dyn
+#define _nolibc_elf_addr Elf32_Addr
+#define _nolibc_elf_r_type(_x) ELF32_R_TYPE(_x)
+#else
+#define _nolibc_elf_ehdr Elf64_Ehdr
+#define _nolibc_elf_phdr Elf64_Phdr
+#define _nolibc_elf_dyn Elf64_Dyn
+#define _nolibc_elf_rela Elf64_Rela
+#define _nolibc_elf_addr Elf64_Addr
+#define _nolibc_elf_r_type(_x) ELF64_R_TYPE(_x)
+#endif
+
+#ifdef _NOLIBC_ARCH_ELF_REL
+#define _nolibc_elf_dt_rel_rela DT_REL
+#define _nolibc_elf_dt_rel_rela_count DT_RELCOUNT
+#else
+#define _nolibc_elf_dt_rel_rela DT_RELA
+#define _nolibc_elf_dt_rel_rela_count DT_RELACOUNT
+#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, _nolibc_elf_rel *entry);
+
+/* Generic implementation of R_x_RELATIVE for REL */
+static __inline__ void __relocate_rel_relative(unsigned long base, _nolibc_elf_rel *entry)
+{
+ _nolibc_elf_addr *addr;
+ int addend;
+
+ addr = (_nolibc_elf_addr *)(base + entry->r_offset);
+ addend = *addr;
+ *addr = base + addend;
+}
+
+static __inline__ int __relocate(unsigned long base,
+ unsigned long rel_off,
+ unsigned long rel_count)
+{
+ _nolibc_elf_rel *rel = (_nolibc_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, _nolibc_elf_rela *entry);
+
+/* Generic implementation of R_x_RELATIVE for RELA */
+static __inline__ void __relocate_rela_relative(unsigned long base, _nolibc_elf_rela *entry)
+{
+ _nolibc_elf_addr *addr;
+
+ addr = (_nolibc_elf_addr *) (base + entry->r_offset);
+ *addr = (_nolibc_elf_addr) (base + entry->r_addend);
+}
+
+static __inline__ int __relocate(unsigned long base,
+ unsigned long rela_off,
+ unsigned long rela_count)
+{
+ _nolibc_elf_rela *rela = (_nolibc_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 __inline__ void _relocate(const unsigned long *auxv)
+{
+ _nolibc_elf_phdr *phdr_dyn = NULL;
+ unsigned long rel_rela_count = 0;
+ unsigned long rel_rela_off = 0;
+ unsigned long phdr_addr = 0;
+ unsigned long phdr_num = 0;
+ _nolibc_elf_ehdr *ehdr;
+ _nolibc_elf_phdr *phdr;
+ _nolibc_elf_dyn *dyn;
+ unsigned long base;
+ unsigned long i;
+ int remaining;
+
+ for (remaining = 2; 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;
+ }
+
+ auxv += 2;
+ }
+
+ if (remaining)
+ goto failed;
+
+ /*
+ * The ELF header and the start of our image in memory
+ * should be the size of the ELF header above the program
+ * headers.
+ */
+ base = phdr_addr - sizeof(_nolibc_elf_ehdr);
+
+ /* Check that we are PIE */
+ ehdr = (_nolibc_elf_ehdr *) base;
+ if (ehdr->e_type != ET_DYN)
+ return;
+
+ phdr = (_nolibc_elf_phdr *) phdr_addr;
+ for (i = 0; i < phdr_num; i++, phdr++) {
+ switch (phdr->p_type) {
+ case PT_INTERP:
+ /* Interp was set, we were relocated already?, return */
+ return;
+ case PT_DYNAMIC:
+ phdr_dyn = phdr;
+ break;
+ }
+ }
+
+ if (!phdr_dyn)
+ goto failed;
+
+ dyn = (_nolibc_elf_dyn *)(base + phdr_dyn->p_vaddr);
+ for (remaining = 2; dyn->d_tag != DT_NULL; dyn++) {
+ switch (dyn->d_tag) {
+ case _nolibc_elf_dt_rel_rela:
+ rel_rela_off = dyn->d_un.d_ptr;
+ remaining--;
+ break;
+ case _nolibc_elf_dt_rel_rela_count:
+ rel_rela_count = dyn->d_un.d_val;
+ remaining--;
+ break;
+ }
+ }
+
+ if (remaining)
+ 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)))
+{
+}
+#endif /* NOLIBC_WANT_RELOC */
+
+#endif /* _NOLIBC_RELOC_H */
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC PATCH v2 04/10] tools/nolibc: m68k: Add relocation support
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
` (2 preceding siblings ...)
2026-02-04 12:45 ` [RFC PATCH v2 03/10] tools/nolibc: Add basic ELF self-relocation support for static PIE Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-16 20:51 ` Thomas Weißschuh
2026-02-04 12:45 ` [RFC PATCH v2 05/10] tools/nolibc: x86: " Daniel Palmer
` (6 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: 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 | 27 ++++++++++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/tools/include/nolibc/arch-m68k.h b/tools/include/nolibc/arch-m68k.h
index 2a4fbada5e79..e82ff48d3fb8 100644
--- a/tools/include/nolibc/arch-m68k.h
+++ b/tools/include/nolibc/arch-m68k.h
@@ -10,8 +10,16 @@
#ifndef _NOLIBC_ARCH_M68K_H
#define _NOLIBC_ARCH_M68K_H
+#include "elf.h"
+
+#ifdef R_68K_RELATIVE
+#define _NOLIBC_ARCH_HAS_RELOC
+#define _NOLIBC_ARCH_ELF32
+#endif
+
#include "compiler.h"
#include "crt.h"
+#include "reloc.h"
#define _NOLIBC_SYSCALL_CLOBBERLIST "memory"
@@ -129,12 +137,29 @@
})
#ifndef NOLIBC_NO_RUNTIME
+
+#ifdef NOLIBC_WANT_RELOC
+static __inline__ int __relocate_rela(unsigned long base, _nolibc_elf_rela *entry)
+{
+ switch (_nolibc_elf_r_type(entry->r_info)) {
+ case R_68K_RELATIVE:
+ __relocate_rela_relative(base, entry);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* NOLIBC_WANT_RELOC */
+
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] 22+ messages in thread
* [RFC PATCH v2 05/10] tools/nolibc: x86: Add relocation support
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
` (3 preceding siblings ...)
2026-02-04 12:45 ` [RFC PATCH v2 04/10] tools/nolibc: m68k: Add relocation support Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-16 21:06 ` Thomas Weißschuh
2026-02-04 12:45 ` [RFC PATCH v2 06/10] tools/nolibc: riscv: " Daniel Palmer
` (5 subsequent siblings)
10 siblings, 1 reply; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: linux-kernel, Daniel Palmer
Add relocation support for x86, both 32bit and 64bit (including x32).
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
tools/include/nolibc/arch-x86.h | 53 +++++++++++++++++++++++++++++++++
1 file changed, 53 insertions(+)
diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h
index f6c43ac5377b..263734c56537 100644
--- a/tools/include/nolibc/arch-x86.h
+++ b/tools/include/nolibc/arch-x86.h
@@ -7,8 +7,29 @@
#ifndef _NOLIBC_ARCH_X86_H
#define _NOLIBC_ARCH_X86_H
+#include "elf.h"
+
+/* x86_64 and x32 */
+#if defined(__x86_64__)
+#if defined(R_AMD64_RELATIVE)
+#define _NOLIBC_ARCH_HAS_RELOC
+#endif
+/* x32 uses ELF32 */
+#if defined(__ILP32__)
+#define _NOLIBC_ARCH_ELF32
+#endif
+/* i386 */
+#else
+#if defined(R_386_RELATIVE)
+#define _NOLIBC_ARCH_HAS_RELOC
+#define _NOLIBC_ARCH_ELF32
+#define _NOLIBC_ARCH_ELF_REL
+#endif
+#endif
+
#include "compiler.h"
#include "crt.h"
+#include "reloc.h"
#if !defined(__x86_64__)
@@ -158,6 +179,22 @@
})
#ifndef NOLIBC_NO_RUNTIME
+
+#ifdef NOLIBC_WANT_RELOC
+static __inline__ int __relocate_rel(unsigned long base, _nolibc_elf_rel *entry)
+{
+ switch (_nolibc_elf_r_type(entry->r_info)) {
+ case R_386_RELATIVE:
+ __relocate_rel_relative(base, entry);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* NOLIBC_WANT_RELOC */
+
/* startup code */
/*
* i386 System V ABI mandates:
@@ -326,6 +363,22 @@ void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _s
})
#ifndef NOLIBC_NO_RUNTIME
+
+#ifdef NOLIBC_WANT_RELOC
+static __inline__ int __relocate_rela(unsigned long base, _nolibc_elf_rela *entry)
+{
+ switch (_nolibc_elf_r_type(entry->r_info)) {
+ case R_AMD64_RELATIVE:
+ __relocate_rela_relative(base, entry);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* NOLIBC_WANT_RELOC */
+
/* startup code */
/*
* x86-64 System V ABI mandates:
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC PATCH v2 06/10] tools/nolibc: riscv: Add relocation support
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
` (4 preceding siblings ...)
2026-02-04 12:45 ` [RFC PATCH v2 05/10] tools/nolibc: x86: " Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 07/10] tools/nolibc: arm: " Daniel Palmer
` (4 subsequent siblings)
10 siblings, 0 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: 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 | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/tools/include/nolibc/arch-riscv.h b/tools/include/nolibc/arch-riscv.h
index 1c00cacf57e1..0a6a4300c318 100644
--- a/tools/include/nolibc/arch-riscv.h
+++ b/tools/include/nolibc/arch-riscv.h
@@ -7,8 +7,18 @@
#ifndef _NOLIBC_ARCH_RISCV_H
#define _NOLIBC_ARCH_RISCV_H
+#include "elf.h"
+
+#ifdef R_RISCV_RELATIVE
+#define _NOLIBC_ARCH_HAS_RELOC
+#if __riscv_xlen == 32
+#define _NOLIBC_ARCH_ELF32
+#endif
+#endif
+
#include "compiler.h"
#include "crt.h"
+#include "reloc.h"
/* Syscalls for RISCV :
* - stack is 16-byte aligned
@@ -140,6 +150,22 @@
})
#ifndef NOLIBC_NO_RUNTIME
+
+#ifdef NOLIBC_WANT_RELOC
+static __inline__ int __relocate_rela(unsigned long base, _nolibc_elf_rela *entry)
+{
+ switch (_nolibc_elf_r_type(entry->r_info)) {
+ case R_RISCV_RELATIVE:
+ __relocate_rela_relative(base, entry);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* NOLIBC_WANT_RELOC */
+
/* startup code */
void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC PATCH v2 07/10] tools/nolibc: arm: Add relocation support
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
` (5 preceding siblings ...)
2026-02-04 12:45 ` [RFC PATCH v2 06/10] tools/nolibc: riscv: " Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 08/10] tools/nolibc: sh: " Daniel Palmer
` (3 subsequent siblings)
10 siblings, 0 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: linux-kernel, Daniel Palmer
Add relocation support for arm.
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
tools/include/nolibc/arch-arm.h | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/tools/include/nolibc/arch-arm.h b/tools/include/nolibc/arch-arm.h
index 251c42579028..0a0d864c857a 100644
--- a/tools/include/nolibc/arch-arm.h
+++ b/tools/include/nolibc/arch-arm.h
@@ -7,8 +7,17 @@
#ifndef _NOLIBC_ARCH_ARM_H
#define _NOLIBC_ARCH_ARM_H
+#include "elf.h"
+
+#ifdef R_ARM_RELATIVE
+#define _NOLIBC_ARCH_HAS_RELOC
+#define _NOLIBC_ARCH_ELF32
+#define _NOLIBC_ARCH_ELF_REL
+#endif
+
#include "compiler.h"
#include "crt.h"
+#include "reloc.h"
/* Syscalls for ARM in ARM or Thumb modes :
* - registers are 32-bit
@@ -185,6 +194,22 @@
})
#ifndef NOLIBC_NO_RUNTIME
+
+#ifdef NOLIBC_WANT_RELOC
+static __inline__ int __relocate_rel(unsigned long base, _nolibc_elf_rel *entry)
+{
+ switch (_nolibc_elf_r_type(entry->r_info)) {
+ case R_ARM_RELATIVE:
+ __relocate_rel_relative(base, entry);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* NOLIBC_WANT_RELOC */
+
/* startup code */
void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC PATCH v2 08/10] tools/nolibc: sh: Add relocation support
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
` (6 preceding siblings ...)
2026-02-04 12:45 ` [RFC PATCH v2 07/10] tools/nolibc: arm: " Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 09/10] tools/nolibc: ppc: " Daniel Palmer
` (2 subsequent siblings)
10 siblings, 0 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: linux-kernel, Daniel Palmer
Add relocation support for SuperH
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
tools/include/nolibc/arch-sh.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/tools/include/nolibc/arch-sh.h b/tools/include/nolibc/arch-sh.h
index 7a421197d104..8e0507977ca1 100644
--- a/tools/include/nolibc/arch-sh.h
+++ b/tools/include/nolibc/arch-sh.h
@@ -7,8 +7,16 @@
#ifndef _NOLIBC_ARCH_SH_H
#define _NOLIBC_ARCH_SH_H
+#include "elf.h"
+
+#ifdef R_SH_RELATIVE
+#define _NOLIBC_ARCH_HAS_RELOC
+#define _NOLIBC_ARCH_ELF32
+#endif
+
#include "compiler.h"
#include "crt.h"
+#include "reloc.h"
/*
* Syscalls for SuperH:
@@ -141,6 +149,22 @@
})
#ifndef NOLIBC_NO_RUNTIME
+
+#ifdef NOLIBC_WANT_RELOC
+static __inline__ int __relocate_rela(unsigned long base, _nolibc_elf_rela *entry)
+{
+ switch (_nolibc_elf_r_type(entry->r_info)) {
+ case R_SH_RELATIVE:
+ __relocate_rela_relative(base, entry);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
/* startup code */
void _start_wrapper(void);
void __attribute__((weak,noreturn)) __nolibc_entrypoint __no_stack_protector _start_wrapper(void)
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC PATCH v2 09/10] tools/nolibc: ppc: Add relocation support
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
` (7 preceding siblings ...)
2026-02-04 12:45 ` [RFC PATCH v2 08/10] tools/nolibc: sh: " Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 10/10] selftests/nolibc: Add option for building with -static-pie Daniel Palmer
2026-02-07 15:34 ` [RFC PATCH v2 00/10] nolibc: Add static-pie support Willy Tarreau
10 siblings, 0 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: linux-kernel, Daniel Palmer
Add relocation support for 32bit and 64bit ppc.
Signed-off-by: Daniel Palmer <daniel@thingy.jp>
---
tools/include/nolibc/arch-powerpc.h | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/tools/include/nolibc/arch-powerpc.h b/tools/include/nolibc/arch-powerpc.h
index e0c7e0b81f7c..a23c41b51cf7 100644
--- a/tools/include/nolibc/arch-powerpc.h
+++ b/tools/include/nolibc/arch-powerpc.h
@@ -7,8 +7,16 @@
#ifndef _NOLIBC_ARCH_POWERPC_H
#define _NOLIBC_ARCH_POWERPC_H
+#include "elf.h"
+
+#define _NOLIBC_ARCH_HAS_RELOC
+#ifndef __powerpc64__
+#define _NOLIBC_ARCH_ELF32
+#endif
+
#include "compiler.h"
#include "crt.h"
+#include "reloc.h"
/* Syscalls for PowerPC :
* - stack is 16-byte aligned
@@ -184,6 +192,22 @@
#endif /* !__powerpc64__ */
#ifndef NOLIBC_NO_RUNTIME
+
+#ifdef NOLIBC_WANT_RELOC
+static __inline__ int __relocate_rela(unsigned long base, _nolibc_elf_rela *entry)
+{
+ switch (_nolibc_elf_r_type(entry->r_info)) {
+ case R_PPC_RELATIVE:
+ __relocate_rela_relative(base, entry);
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* NOLIBC_WANT_RELOC */
+
/* startup code */
void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void)
{
--
2.51.0
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [RFC PATCH v2 10/10] selftests/nolibc: Add option for building with -static-pie
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
` (8 preceding siblings ...)
2026-02-04 12:45 ` [RFC PATCH v2 09/10] tools/nolibc: ppc: " Daniel Palmer
@ 2026-02-04 12:45 ` Daniel Palmer
2026-02-16 20:59 ` Thomas Weißschuh
2026-02-07 15:34 ` [RFC PATCH v2 00/10] nolibc: Add static-pie support Willy Tarreau
10 siblings, 1 reply; 22+ messages in thread
From: Daniel Palmer @ 2026-02-04 12:45 UTC (permalink / raw)
To: w, linux; +Cc: 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] 22+ messages in thread
* Re: [RFC PATCH v2 00/10] nolibc: Add static-pie support
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
` (9 preceding siblings ...)
2026-02-04 12:45 ` [RFC PATCH v2 10/10] selftests/nolibc: Add option for building with -static-pie Daniel Palmer
@ 2026-02-07 15:34 ` Willy Tarreau
2026-02-08 1:35 ` Daniel Palmer
10 siblings, 1 reply; 22+ messages in thread
From: Willy Tarreau @ 2026-02-07 15:34 UTC (permalink / raw)
To: Daniel Palmer; +Cc: linux, linux-kernel
Hi Daniel,
On Wed, Feb 04, 2026 at 09:45:32PM +0900, Daniel Palmer wrote:
> v2:
>
> - This is still RFC quality
> - I have gotten a few more archs to work (not crash in nolibc-test) so I have added them
> to show the that the arch specific parts are pretty small.
> - This should now only add this extra code if NOLIBC_WANT_RELOC is defined, which happens
> automatically if you compile with -fpie. Should address Willy's concern with the size
> blowing up for even binaries that don't need this.
Oh yes that's a nice improvement indeed, thank you:
$ size init-master init-dpalmer*
text data bss dec hex filename
22519 24 39424 61967 f20f init-master
22562 24 39424 62010 f23a init-dpalmer
22710 56 39424 62190 f2ee init-dpalmer-pie
22816 24 39424 62264 f338 init-dpalmer-want-reloc
I think the 43 bytes increase on the _start_c part remains acceptable,
especially compared to the +300 before :-)
> Size difference on ppc64 is massive, I guess PIC code is big there.
>
> static:
>
> $ file nolibc-test
> nolibc-test: ELF 64-bit MSB executable, 64-bit PowerPC or cisco 7500, Power ELF V1 ABI, version 1 (SYSV), statically linked, not stripped
> $ size nolibc-test
> text data bss dec hex filename
> 59560 3240 104 62904 f5b8 nolibc-test
>
> static pie:
>
> $ file nolibc-test
> nolibc-test: ELF 64-bit MSB pie executable, 64-bit PowerPC or cisco 7500, Power ELF V1 ABI, version 1 (SYSV), static-pie linked, with debug_info, not stripped
> $ size nolibc-test
> text data bss dec hex filename
> 67801 3656 104 71561 11789 nolibc-test
>
> - Each of the archs checks that the relocations they need (just the one at the moment) is defined
> before defining the relocation defines. So this shouldn't break with older UAPI headers.
I confirm, I've built against 5.10 to 6.18 and it's OK, and if -fpie
is passed we get an error saying the arch doesn't support it.
> - I think maybe you might want to set NOLIBC_WANT_RELOC even if __pie__ is not defined,
> maybe for testing? So I didn't make it _NOLIBC_WANT_RELOC.
It's possible, at least for developers/maintainers maybe. Above I used it
to compare the size increase caused by the changes.
> - I was worried some archs didn't work because calling the relocation functions was
> causing things like accessing the stack canary before it was accessible. So I added
> __inline__ to all of the relocation functions to force them to get inlined into _start_c().
If you absolutely need to forcefully inline, you should add
__attribute__((always_inline)) in addition to __inline__, as
it will override the default compiler setting based on the
optimization level. However the functions are short enough
that they were always inlined in my tests regardless of the
attribute.
> This might be too much. checkpatch certainly hates it.
No big deal.
Thanks,
Willy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc
2026-02-04 12:45 ` [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc Daniel Palmer
@ 2026-02-07 15:35 ` Willy Tarreau
2026-02-16 20:33 ` Thomas Weißschuh
1 sibling, 0 replies; 22+ messages in thread
From: Willy Tarreau @ 2026-02-07 15:35 UTC (permalink / raw)
To: Daniel Palmer; +Cc: linux, linux-kernel
On Wed, Feb 04, 2026 at 09:45:33PM +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
> +
> +#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
Maybe a comment indicating where to find these values would be helpful
for future architectures ?
Willy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts
2026-02-04 12:45 ` [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts Daniel Palmer
@ 2026-02-07 15:45 ` Willy Tarreau
2026-02-08 1:40 ` Daniel Palmer
2026-02-16 20:42 ` Thomas Weißschuh
1 sibling, 1 reply; 22+ messages in thread
From: Willy Tarreau @ 2026-02-07 15:45 UTC (permalink / raw)
To: Daniel Palmer; +Cc: linux, linux-kernel
On Wed, Feb 04, 2026 at 09:45:34PM +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/compiler.h | 6 ++++
> tools/include/nolibc/crt.h | 57 ++++++++++++++++++---------------
> 2 files changed, 38 insertions(+), 25 deletions(-)
>
> diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compiler.h
> index 87090bbc53e0..3f403e54e4f4 100644
> --- a/tools/include/nolibc/compiler.h
> +++ b/tools/include/nolibc/compiler.h
> @@ -47,4 +47,10 @@
> # define __nolibc_fallthrough do { } while (0)
> #endif /* __nolibc_has_attribute(fallthrough) */
>
> +#if __nolibc_has_feature(undefined_behavior_sanitizer)
> +# define __no_sanitize __attribute__((no_sanitize("function")))
> +#else
> +# define __no_sanitize
> +#endif
I'm starting to feel uncomfortable with the addition of new __no_foo
stuff, which doesn't have the "nolibc" prefix, risking to conflict with
userland code. I think we'll have to go through a cleanup patch at some
point for __no_sanitize and __no_stack_protector.
So probably in order to reduce the technical debt it would be nice to
to prepend __nolibc in front of this new internal macro. Maybe this part
of the patch should be a separate cleanup patch by the way, as future
patches might depend on it.
Willy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 03/10] tools/nolibc: Add basic ELF self-relocation support for static PIE
2026-02-04 12:45 ` [RFC PATCH v2 03/10] tools/nolibc: Add basic ELF self-relocation support for static PIE Daniel Palmer
@ 2026-02-07 15:49 ` Willy Tarreau
0 siblings, 0 replies; 22+ messages in thread
From: Willy Tarreau @ 2026-02-07 15:49 UTC (permalink / raw)
To: Daniel Palmer; +Cc: linux, linux-kernel
On Wed, Feb 04, 2026 at 09:45:35PM +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 other 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 ELF program header address
> given to us by the kernel and the size of the ELF header that
> should be directly above.
> - 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.
So we're clearly past my knowledge of these things and will have to
trust you :-)
One thing however, please keep in mind that all your _relocate and
__relocate* functions will be visible from userland code and as such
should be prefixed with "_nolibc" (or even __nolibc) to prevent name
conflicts. It's a particular effort we have to do that is caused by
the lib's design consisting only in include files: nothing at all
is private.
Willy
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 00/10] nolibc: Add static-pie support
2026-02-07 15:34 ` [RFC PATCH v2 00/10] nolibc: Add static-pie support Willy Tarreau
@ 2026-02-08 1:35 ` Daniel Palmer
0 siblings, 0 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-08 1:35 UTC (permalink / raw)
To: Willy Tarreau; +Cc: linux, linux-kernel
Hi Willy,
Thank you for taking the time to look at this.
On Sun, 8 Feb 2026 at 00:34, Willy Tarreau <w@1wt.eu> wrote:
> If you absolutely need to forcefully inline, you should add
> __attribute__((always_inline)) in addition to __inline__, as
> it will override the default compiler setting based on the
> optimization level. However the functions are short enough
> that they were always inlined in my tests regardless of the
> attribute.
Noted. Like you said I think the functions always get inlined so the
problem is theoretical.
I think actually just disabling the stack projector for the functions
will be enough if the compiler ever decides not to inline.
I guess I'll try the opposite and force the compiler not to inline and
see if it breaks.
Thanks,
Daniel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts
2026-02-07 15:45 ` Willy Tarreau
@ 2026-02-08 1:40 ` Daniel Palmer
0 siblings, 0 replies; 22+ messages in thread
From: Daniel Palmer @ 2026-02-08 1:40 UTC (permalink / raw)
To: Willy Tarreau; +Cc: linux, linux-kernel
Hi Willy,
On Sun, 8 Feb 2026 at 00:45, Willy Tarreau <w@1wt.eu> wrote:
> > +#if __nolibc_has_feature(undefined_behavior_sanitizer)
> > +# define __no_sanitize __attribute__((no_sanitize("function")))
> > +#else
> > +# define __no_sanitize
> > +#endif
>
> I'm starting to feel uncomfortable with the addition of new __no_foo
> stuff, which doesn't have the "nolibc" prefix, risking to conflict with
> userland code. I think we'll have to go through a cleanup patch at some
> point for __no_sanitize and __no_stack_protector.
>
> So probably in order to reduce the technical debt it would be nice to
> to prepend __nolibc in front of this new internal macro. Maybe this part
> of the patch should be a separate cleanup patch by the way, as future
> patches might depend on it.
Since this relocation thing will still take more time I will create a
set of patches just to add the prefix to __no_stack_protector, add
__nolibc_no_sanitize and use it in crt.h to send now instead of as
part of this.
Cheers,
Daniel
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc
2026-02-04 12:45 ` [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc Daniel Palmer
2026-02-07 15:35 ` Willy Tarreau
@ 2026-02-16 20:33 ` Thomas Weißschuh
1 sibling, 0 replies; 22+ messages in thread
From: Thomas Weißschuh @ 2026-02-16 20:33 UTC (permalink / raw)
To: Daniel Palmer; +Cc: w, linux-kernel
On 2026-02-04 21:45:33+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.
For the final version of this patch the UAPI headers will need all
relocation types for all architectures. Otherwise the kernel build will break.
I can do this migration, as I'll need it for some other things anyways.
Could you add a comment to this effect to the patch?
>
> 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;
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts
2026-02-04 12:45 ` [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts Daniel Palmer
2026-02-07 15:45 ` Willy Tarreau
@ 2026-02-16 20:42 ` Thomas Weißschuh
1 sibling, 0 replies; 22+ messages in thread
From: Thomas Weißschuh @ 2026-02-16 20:42 UTC (permalink / raw)
To: Daniel Palmer; +Cc: w, linux-kernel
On 2026-02-04 21:45:34+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/compiler.h | 6 ++++
> tools/include/nolibc/crt.h | 57 ++++++++++++++++++---------------
> 2 files changed, 38 insertions(+), 25 deletions(-)
>
> diff --git a/tools/include/nolibc/compiler.h b/tools/include/nolibc/compiler.h
> index 87090bbc53e0..3f403e54e4f4 100644
> --- a/tools/include/nolibc/compiler.h
> +++ b/tools/include/nolibc/compiler.h
> @@ -47,4 +47,10 @@
> # define __nolibc_fallthrough do { } while (0)
> #endif /* __nolibc_has_attribute(fallthrough) */
>
> +#if __nolibc_has_feature(undefined_behavior_sanitizer)
> +# define __no_sanitize __attribute__((no_sanitize("function")))
> +#else
> +# define __no_sanitize
> +#endif
> +
> #endif /* _NOLIBC_COMPILER_H */
> diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
> index d9262998dae9..fab042f1ff62 100644
> --- a/tools/include/nolibc/crt.h
> +++ b/tools/include/nolibc/crt.h
> @@ -27,26 +27,45 @@ 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))
> -#if __nolibc_has_feature(undefined_behavior_sanitizer)
> - __attribute__((no_sanitize("function")))
> -#endif
> -void _start_c(long *sp)
> +void _start_c_global_data(long argc, char **argv, char **envp, const unsigned long *auxv);
> +__attribute__((weak, used))
The compiler can see that this function is used below, so the attribute
'used' can be dropped.
When not building for 'pie' the 'weak' attribute is also not needed.
It should be 'static' so the function can be inlined again.
Theoretically this should also save some bytes. However in my testing it
generates slightly larger code. So I'm not sure what to do here.
> +void __no_sanitize __no_stack_protector _start_c_global_data(long argc, char **argv, char **envp, const unsigned long *auxv)
> {
(...)
> +}
> +
> +void _start_c(long *sp);
> +__attribute__((weak, used))
> +void __no_sanitize __no_stack_protector _start_c(long *sp)
> +{
(...)
> + _start_c_global_data(argc, argv, envp, auxv);
> }
>
> #endif /* NOLIBC_NO_RUNTIME */
> --
> 2.51.0
>
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 04/10] tools/nolibc: m68k: Add relocation support
2026-02-04 12:45 ` [RFC PATCH v2 04/10] tools/nolibc: m68k: Add relocation support Daniel Palmer
@ 2026-02-16 20:51 ` Thomas Weißschuh
0 siblings, 0 replies; 22+ messages in thread
From: Thomas Weißschuh @ 2026-02-16 20:51 UTC (permalink / raw)
To: Daniel Palmer; +Cc: w, linux-kernel
On 2026-02-04 21:45:36+0900, Daniel Palmer wrote:
> 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.
You are the expert here, so some more definitive answer to this question
would be nice :-)
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
> tools/include/nolibc/arch-m68k.h | 27 ++++++++++++++++++++++++++-
> 1 file changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/tools/include/nolibc/arch-m68k.h b/tools/include/nolibc/arch-m68k.h
> index 2a4fbada5e79..e82ff48d3fb8 100644
> --- a/tools/include/nolibc/arch-m68k.h
> +++ b/tools/include/nolibc/arch-m68k.h
> @@ -10,8 +10,16 @@
> #ifndef _NOLIBC_ARCH_M68K_H
> #define _NOLIBC_ARCH_M68K_H
>
> +#include "elf.h"
> +
> +#ifdef R_68K_RELATIVE
> +#define _NOLIBC_ARCH_HAS_RELOC
> +#define _NOLIBC_ARCH_ELF32
> +#endif
> +
> #include "compiler.h"
> #include "crt.h"
> +#include "reloc.h"
>
> #define _NOLIBC_SYSCALL_CLOBBERLIST "memory"
>
> @@ -129,12 +137,29 @@
> })
>
> #ifndef NOLIBC_NO_RUNTIME
> +
> +#ifdef NOLIBC_WANT_RELOC
> +static __inline__ int __relocate_rela(unsigned long base, _nolibc_elf_rela *entry)
> +{
> + switch (_nolibc_elf_r_type(entry->r_info)) {
> + case R_68K_RELATIVE:
It seems there is only ever a single relocation used per architecture.
So wouldn't it be possible to do something like this:
#define _NOLIBC_ARCH_HAS_RELOC
#define _NOLIBC_ARCH_RELA_RELOC R_68K_RELATIVE
This keeps the per-architecture code simpler and removes the ugly
'ifdef R_68K_RELATIVE'. The code will break if somebody actually tries
to build a static pie using old uapi headers, but then this has never
worked before anyways.
> + __relocate_rela_relative(base, entry);
> + break;
> + default:
> + return -1;
> + }
> +
> + return 0;
> +}
> +#endif /* NOLIBC_WANT_RELOC */
> +
> 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 [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 10/10] selftests/nolibc: Add option for building with -static-pie
2026-02-04 12:45 ` [RFC PATCH v2 10/10] selftests/nolibc: Add option for building with -static-pie Daniel Palmer
@ 2026-02-16 20:59 ` Thomas Weißschuh
0 siblings, 0 replies; 22+ messages in thread
From: Thomas Weißschuh @ 2026-02-16 20:59 UTC (permalink / raw)
To: Daniel Palmer; +Cc: w, linux-kernel
On 2026-02-04 21:45:42+0900, Daniel Palmer wrote:
> 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)
It seems the -static is not necessary, even today.
Maybe split this into its own commit with some explanation to make this
clearer.
>
> 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"
The -ggdb shouldn't be necessary here, or?
> + 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 [flat|nested] 22+ messages in thread
* Re: [RFC PATCH v2 05/10] tools/nolibc: x86: Add relocation support
2026-02-04 12:45 ` [RFC PATCH v2 05/10] tools/nolibc: x86: " Daniel Palmer
@ 2026-02-16 21:06 ` Thomas Weißschuh
0 siblings, 0 replies; 22+ messages in thread
From: Thomas Weißschuh @ 2026-02-16 21:06 UTC (permalink / raw)
To: Daniel Palmer; +Cc: w, linux-kernel
On 2026-02-04 21:45:37+0900, Daniel Palmer wrote:
> Add relocation support for x86, both 32bit and 64bit (including x32).
>
> Signed-off-by: Daniel Palmer <daniel@thingy.jp>
> ---
> tools/include/nolibc/arch-x86.h | 53 +++++++++++++++++++++++++++++++++
> 1 file changed, 53 insertions(+)
>
> diff --git a/tools/include/nolibc/arch-x86.h b/tools/include/nolibc/arch-x86.h
> index f6c43ac5377b..263734c56537 100644
> --- a/tools/include/nolibc/arch-x86.h
> +++ b/tools/include/nolibc/arch-x86.h
> @@ -7,8 +7,29 @@
> #ifndef _NOLIBC_ARCH_X86_H
> #define _NOLIBC_ARCH_X86_H
>
> +#include "elf.h"
> +
> +/* x86_64 and x32 */
> +#if defined(__x86_64__)
> +#if defined(R_AMD64_RELATIVE)
> +#define _NOLIBC_ARCH_HAS_RELOC
> +#endif
> +/* x32 uses ELF32 */
> +#if defined(__ILP32__)
> +#define _NOLIBC_ARCH_ELF32
> +#endif
> +/* i386 */
> +#else
> +#if defined(R_386_RELATIVE)
> +#define _NOLIBC_ARCH_HAS_RELOC
> +#define _NOLIBC_ARCH_ELF32
> +#define _NOLIBC_ARCH_ELF_REL
> +#endif
> +#endif
This preprocessor soup would be easier to read like this:
/* x86_64 and x32 */
#if defined(__x86_64__) && defined(R_AMD64_RELATIVE)
#define _NOLIBC_ARCH_HAS_RELOC
#endif
/* x32 uses ELF32 */
#if defined(__x86_64__) && defined(__ILP32__)
#define _NOLIBC_ARCH_ELF32
#endif
/* i386 */
#if !defined(__x86_64__) && defined(R_386_RELATIVE)
#define _NOLIBC_ARCH_HAS_RELOC
#define _NOLIBC_ARCH_ELF32
#define _NOLIBC_ARCH_ELF_REL
#endif
The code style for nolibc nowadays is 'defined(FOO)' over '#ifdef FOO'.
> +
> #include "compiler.h"
> #include "crt.h"
> +#include "reloc.h"
>
> #if !defined(__x86_64__)
>
> @@ -158,6 +179,22 @@
> })
(...)
^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2026-02-16 21:06 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-04 12:45 [RFC PATCH v2 00/10] nolibc: Add static-pie support Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 01/10] elf: Add relocation types used by nolibc Daniel Palmer
2026-02-07 15:35 ` Willy Tarreau
2026-02-16 20:33 ` Thomas Weißschuh
2026-02-04 12:45 ` [RFC PATCH v2 02/10] tools/nolibc: crt: Split _start_c() into stack-only and normal parts Daniel Palmer
2026-02-07 15:45 ` Willy Tarreau
2026-02-08 1:40 ` Daniel Palmer
2026-02-16 20:42 ` Thomas Weißschuh
2026-02-04 12:45 ` [RFC PATCH v2 03/10] tools/nolibc: Add basic ELF self-relocation support for static PIE Daniel Palmer
2026-02-07 15:49 ` Willy Tarreau
2026-02-04 12:45 ` [RFC PATCH v2 04/10] tools/nolibc: m68k: Add relocation support Daniel Palmer
2026-02-16 20:51 ` Thomas Weißschuh
2026-02-04 12:45 ` [RFC PATCH v2 05/10] tools/nolibc: x86: " Daniel Palmer
2026-02-16 21:06 ` Thomas Weißschuh
2026-02-04 12:45 ` [RFC PATCH v2 06/10] tools/nolibc: riscv: " Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 07/10] tools/nolibc: arm: " Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 08/10] tools/nolibc: sh: " Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 09/10] tools/nolibc: ppc: " Daniel Palmer
2026-02-04 12:45 ` [RFC PATCH v2 10/10] selftests/nolibc: Add option for building with -static-pie Daniel Palmer
2026-02-16 20:59 ` Thomas Weißschuh
2026-02-07 15:34 ` [RFC PATCH v2 00/10] nolibc: Add static-pie support Willy Tarreau
2026-02-08 1:35 ` Daniel Palmer
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox