public inbox for linux-m68k@lists.linux-m68k.org
 help / color / mirror / Atom feed
From: Daniel Palmer <daniel@thingy.jp>
To: w@1wt.eu, linux@weissschuh.net, gerg@linux-m68k.org, dalias@libc.org
Cc: linux-m68k@lists.linux-m68k.org, linux-kernel@vger.kernel.org,
	Daniel Palmer <daniel@thingy.jp>
Subject: [RFC PATCH] tools/nolibc: HACK!: Add basic self relocation for static PIE for m68k nommu FDPIC
Date: Fri, 16 Jan 2026 21:28:12 +0900	[thread overview]
Message-ID: <20260116122812.2421621-1-daniel@thingy.jp> (raw)

This is some very quick hacky code to test if this works and get some ideas..

- I'm messing with m68k nommu. Currently I use FLAT binaries and this is working with nolibc
  as-is mostly. Sometimes some relocations that elf2flat doesn't like get generated and the
  resulting FLAT binary doesn't have any relocation information and crashes which isn't good
  if you don't have an mmu.

- Since commit 1bde925d2354 ("fs/binfmt_elf_fdpic.c: provide NOMMU loader for regular ELF binaries")
  the FDPIC loader has apparently been able to load non-FDPIC binaries as long as they are
  PIE and can be relocated. I have been messing with this thinking that maybe I can stop using
  FLAT binaries.

- By default linking with -pie is trying to set ld.so as the interpreter to do the
  relocation. I don't think I have anything that can do that in my system. I am using uclibc but
  statically linked. Aside from my programs written with nolibc there is a busybox FLAT that is
  statically linked to uclibc and nothing else.

  Eitherway, the plan is not to have any libc and have everything compiled with nolibc. I'm writing
  a small init, shell etc with nolibc that will replace busybox and not cause constant OOMs.

- So, I can generate PIE binaries but they can't work because I have no linker to relocate them but
  apparently static PIE is a thing and with a normal toolchain you'd get a crt that does the relocation
  before jumping to main().

- I thought it shouldn't be too hard to add something like that to crt.h in nolibc and then pass
  --no-dynamic-linker when linking to not set an interpreter.

- I got it working enough that a static pie "hello, world" loads and runs:

/ # /root/test.elf
[    9.970000] FDPIC ____ LOAD 23 ____
[    9.970000] FDPIC Mapped Object [executable]:
[    9.970000] FDPIC - elfhdr   : 6d8000
[    9.970000] FDPIC - entry    : 6d83e4
[    9.970000] FDPIC - PHDR[]   : 6d8034
[    9.970000] FDPIC - DYNAMIC[]: 6da7b0
[    9.970000] FDPIC - LOAD[0] : 006d8000-006d87ad [va=0 ms=7ae]
[    9.970000] FDPIC - LOAD[1] : 006da7b0-006da873 [va=27b0 ms=c4]
[    9.970000] FDPIC - start_code  6d8000
[    9.970000] FDPIC - end_code    6d87ae
[    9.970000] FDPIC - start_data  6da7b0
[    9.970000] FDPIC - end_data    6da874
[    9.970000] FDPIC - start_brk   6e0000
[    9.970000] FDPIC - brk         6e0000
[    9.970000] FDPIC - start_stack 6fff00
hello, world!
[    9.980000] test.elf (23) used greatest stack depth: 5348 bytes left

Questions:

- My use case is weird/niche but maybe there are uses for static pie nolibc binaries?
  - If so what would be a cleaner way of implementing this?

- Right now the base address offset all of the relocations against is hardcoded.
  Maybe someone knows how I'm meant to get that properly?

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

diff --git a/tools/include/nolibc/crt.h b/tools/include/nolibc/crt.h
index d9262998dae9..0931915280d8 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 "elf.h"
 
 char **environ __attribute__((weak));
 const unsigned long *_auxv __attribute__((weak));
@@ -47,6 +48,61 @@ void _start_c(long *sp)
 	/* initialize stack protector */
 	__stack_chk_init();
 
+#ifdef NOLIBC_STATIC_PIE
+#define R_68K_RELATIVE	22
+{
+	void *base = (void *) 0x6d8000; // TODO: how to actually get this?
+	unsigned int rela_count = 0;
+	unsigned int rela_off = 0;
+	unsigned long dyn_addr;
+	Elf32_Rela *rela;
+	Elf32_Addr *addr;
+	Elf32_Dyn *dyn;
+	int i;
+
+	/* For m68k with the FDPIC loader d5 contains the offset to the DYNAMIC segment */
+	__asm__ volatile (
+		"move.l %%d5, %0\n"
+		: "=r" (dyn_addr)
+	);
+	dyn = (Elf32_Dyn *) dyn_addr;
+
+	/* Go through the DYNAMIC segment and get the offset to rela and the number of relocations */
+	for (; dyn->d_tag != DT_NULL; dyn++) {
+		switch (dyn->d_tag) {
+		case DT_RELA:
+			rela_off = dyn->d_un.d_ptr;
+			break;
+		case DT_RELACOUNT:
+			rela_count = dyn->d_un.d_val;
+			break;
+		}
+	}
+
+	if (!rela_off || !rela_count)
+		exit(42); //TODO nonsense error
+
+	rela = base + rela_off;
+
+	/* Do the relocations, only R_68K_RELATIVE for now */
+	for (i = 0; i < rela_count; i++) {
+		Elf32_Rela *entry = &rela[i];
+
+		switch (ELF32_R_TYPE(entry->r_info)) {
+		case R_68K_RELATIVE:
+		{
+			addr = (Elf32_Addr *)(base + entry->r_offset);
+			*addr = (Elf32_Addr) (base + entry->r_addend);
+		}
+			break;
+		default:
+			exit(43); //TODO nonsense error
+			break;
+		}
+	}
+}
+#endif
+
 	/*
 	 * sp  :    argc          <-- argument count, required by main()
 	 * argv:    argv[0]       <-- argument vector, required by main()
-- 
2.51.0


             reply	other threads:[~2026-01-16 12:28 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-16 12:28 Daniel Palmer [this message]
2026-01-16 13:09 ` [RFC PATCH] tools/nolibc: HACK!: Add basic self relocation for static PIE for m68k nommu FDPIC Greg Ungerer
2026-01-16 19:29 ` Thomas Weißschuh
2026-01-19  9:58   ` Daniel Palmer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260116122812.2421621-1-daniel@thingy.jp \
    --to=daniel@thingy.jp \
    --cc=dalias@libc.org \
    --cc=gerg@linux-m68k.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-m68k@lists.linux-m68k.org \
    --cc=linux@weissschuh.net \
    --cc=w@1wt.eu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox