]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[riscv] Split out runtime relocator to libprefix.S
authorMichael Brown <mcb30@ipxe.org>
Thu, 1 May 2025 13:04:27 +0000 (14:04 +0100)
committerMichael Brown <mcb30@ipxe.org>
Thu, 1 May 2025 13:36:26 +0000 (14:36 +0100)
Split out the runtime relocation logic from sbiprefix.S to a new
library libprefix.S.

Since this logically decouples the process of runtime relocation from
the _sbi_start symbol (currently used to determine the base address
for applying relocations), provide an alternative mechanism for the
relocator to determine the base address.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/riscv/prefix/libprefix.S [new file with mode: 0644]
src/arch/riscv/prefix/sbiprefix.S
src/arch/riscv/scripts/sbi.lds

diff --git a/src/arch/riscv/prefix/libprefix.S b/src/arch/riscv/prefix/libprefix.S
new file mode 100644 (file)
index 0000000..7f4d570
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2025 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ * You can also choose to distribute this program under the terms of
+ * the Unmodified Binary Distribution Licence (as given in the file
+ * COPYING.UBDL), provided that you have satisfied its requirements.
+ */
+
+       FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL )
+
+/** @file
+ *
+ * RISC-V prefix library
+ *
+ */
+
+       .section ".note.GNU-stack", "", @progbits
+       .text
+
+/*****************************************************************************
+ *
+ * Apply relocation records
+ *
+ *****************************************************************************
+ *
+ * Apply relocation records from .rel.dyn to fix up iPXE to run at its
+ * current address.
+ *
+ * This function must run before .bss is zeroed (since the relocation
+ * records are overlaid with .bss).  It does not require a valid stack
+ * pointer.
+ *
+ * Parameters: none (address is implicit in the program counter)
+ *
+ * Returns: none
+ *
+ */
+
+/* Relative relocation type */
+#define R_RISCV_RELATIVE 3
+
+       /* Layout of a relocation record */
+       .struct 0
+rela_offset:   .space ( __riscv_xlen / 8 )
+rela_type:     .space ( __riscv_xlen / 8 )
+rela_addend:   .space ( __riscv_xlen / 8 )
+rela_len:
+       .previous
+
+       .section ".prefix.apply_relocs", "ax", @progbits
+       .globl  apply_relocs
+apply_relocs:
+
+       /* Get relocation records */
+       la      t0, _reloc
+       la      t1, _ereloc
+
+       /* Determine current location */
+       la      t2, reloc_base
+       LOADN   t2, (t2)
+       sub     t2, t0, t2
+
+1:     /* Read relocation record */
+       LOADN   t3, rela_offset(t0)
+       LOADN   t4, rela_type(t0)
+       LOADN   t5, rela_addend(t0)
+
+       /* Check relocation type */
+       addi    t4, t4, -R_RISCV_RELATIVE
+       bnez    t4, 2f
+
+       /* Apply relocation */
+       add     t3, t3, t2
+       add     t5, t5, t2
+       STOREN  t5, (t3)
+2:
+       /* Loop until done */
+       addi    t0, t0, rela_len
+       blt     t0, t1, 1b
+
+       /* Return to caller */
+       ret
+       .size   apply_relocs, . - apply_relocs
+
+       /* Link-time address of _reloc */
+       .section ".rodata", "a", @progbits
+reloc_base:
+       .dword  _reloc_base
+       .size   reloc_base, . - reloc_base
index e8ef40b6def730f7e727945680a0a844224a5af2..ccf8b0743fcba8fb53a0685ac4b5ff18dfb926cc 100644 (file)
 #define SBI_SRST_SYSTEM_RESET 0x00
 #define SBI_RESET_COLD 0x00000001
 
-/* Relative relocation type */
-#define R_RISCV_RELATIVE 3
-
-       /* Layout of a relocation record */
-       .struct 0
-rela_offset:   .space ( __riscv_xlen / 8 )
-rela_type:     .space ( __riscv_xlen / 8 )
-rela_addend:   .space ( __riscv_xlen / 8 )
-rela_len:
-       .previous
-
        /*
         * Display progress message via debug console
         */
@@ -85,23 +74,7 @@ _sbi_start:
        progress "\nSBI->iPXE"
 
        /* Apply dynamic relocations */
-       la      t0, _reloc
-       la      t1, _ereloc
-       la      t2, _sbi_start
-1:     /* Read relocation record */
-       LOADN   t3, rela_offset(t0)
-       LOADN   t4, rela_type(t0)
-       LOADN   t5, rela_addend(t0)
-       /* Check relocation type */
-       addi    t4, t4, -R_RISCV_RELATIVE
-       bnez    t4, 2f
-       /* Apply relocation */
-       add     t3, t3, t2
-       add     t5, t5, t2
-       STOREN  t5, (t3)
-2:     /* Loop */
-       addi    t0, t0, rela_len
-       blt     t0, t1, 1b
+       call    apply_relocs
        progress " .reloc"
 
        /* Zero the bss */
index a65b271819b7d94ffeb436c6ac965fdb33a76259..afb1902e1962f13532ccf6db8771d49f7c58e1e3 100644 (file)
@@ -87,6 +87,14 @@ SECTIONS {
        }
     }
 
+    /* Absolute link-time address of _reloc
+     *
+     * The runtime relocator needs to know the link-time addresses.
+     * Since RISC-V uses .rela (rather than .rel), the only way to
+     * expose this to the relocator is via an absolute symbol.
+     */
+    _reloc_base = ABSOLUTE ( _reloc );
+
     /* Calculate end of relocations
      *
      * This cannot be done by placing "_ereloc = .;" inside the