mirror of
https://github.com/ipxe/ipxe
synced 2025-12-16 01:21:10 +03:00
[riscv] Split out runtime relocator to libprefix.S
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>
This commit is contained in:
104
src/arch/riscv/prefix/libprefix.S
Normal file
104
src/arch/riscv/prefix/libprefix.S
Normal file
@@ -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
|
||||
@@ -41,17 +41,6 @@
|
||||
#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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user