From: Evgeny Karpov <[email protected]>
Subject: [PATCH] aarch64: Add runtime relocations

The patch implements the required changes to support runtime relocations.
For 26-bit relocation, the linker generates a jump stub, as a single
opcode is not sufficient for relocation.

The supporting binutils patch is being upstreamed.
https://sourceware.org/pipermail/binutils/2025-November/145651.html

A similar change has been upstreamed to Cygwin.
https://cygwin.com/pipermail/cygwin-patches/2025q4/014332.html

Signed-off-by: Evgeny Karpov <[email protected]>
---
 mingw-w64-crt/crt/pseudo-reloc.c | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/mingw-w64-crt/crt/pseudo-reloc.c b/mingw-w64-crt/crt/pseudo-reloc.c
index dd08e718a..20c04a1f0 100644
--- a/mingw-w64-crt/crt/pseudo-reloc.c
+++ b/mingw-w64-crt/crt/pseudo-reloc.c
@@ -464,6 +464,31 @@ do_pseudo_reloc (void * start, void * end, void * base)
         case 16:
            __write_memory ((void *) reloc_target, &reldata, 2);
           break;
+#ifdef __aarch64__
+        case 12:
+          /* Replace add Xn, Xn, :lo12:label with ldr Xn, [Xn, 
:lo12:__imp__func].
+             That loads the address of _func into Xn.  */
+          opcode = 0xf9400000 | (opcode & 0x3ff); // ldr
+          reldata = ((ptrdiff_t) base + r->sym) & ((1 << 12) - 1);
+          reldata >>= 3;
+          opcode |= reldata << 10;
+           __write_memory ((void *) reloc_target, &opcode, 4);
+          break;
+        case 21:
+          /* Replace adrp Xn, label with adrp Xn, __imp__func.  */
+          opcode &= 0x9f00001f;
+          reldata = (((ptrdiff_t) base + r->sym) >> 12)
+                    - (((ptrdiff_t) base + r->target) >> 12);
+          reldata &= (1 << 21) - 1;
+          opcode |= (reldata & 3) << 29;
+          reldata >>= 2;
+          opcode |= reldata << 5;
+           __write_memory ((void *) reloc_target, &opcode, 4);
+          break;
+        /* A note regarding 26 bits relocation.
+           A single opcode is not sufficient for 26 bits relocation in dynamic 
linking.
+           The linker generates a jump stub instead.  */
+#endif
         case 32:
            __write_memory ((void *) reloc_target, &reldata, 4);
           break;
-- 
2.50.1 (Apple Git-155)

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to