[PATCH 1/8] riscv: Optimize source end address calculation in start.S

The __bss_start is the source end address hence load its address directly into register 't2' for optimization.
Signed-off-by: Bin Meng bmeng@tinylab.org ---
arch/riscv/cpu/start.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 4687bca3c9..3c8344c345 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -283,9 +283,7 @@ stack_setup: beq t0, s4, clear_bss /* skip relocation */
mv t1, s4 /* t1 <- scratch for copy_loop */ - la t3, __bss_start - sub t3, t3, t0 /* t3 <- __bss_start_ofs */ - add t2, t0, t3 /* t2 <- source end address */ + la t2, __bss_start /* t2 <- source end address */
copy_loop: LREG t5, 0(t0)

't5' already contains relocation type so don't bother reloading it.
Signed-off-by: Bin Meng bmeng@tinylab.org ---
arch/riscv/cpu/start.S | 1 - 1 file changed, 1 deletion(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 3c8344c345..879bdc1803 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -323,7 +323,6 @@ fix_rela_dyn: add t4, t4, t6
9: - LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ srli t0, t5, SYM_INDEX /* t0 <--- sym table index */ andi t5, t5, 0xFF /* t5 <--- relocation type */ li t3, RELOC_TYPE

Some coding convention fixes.
Signed-off-by: Bin Meng bmeng@tinylab.org ---
tools/prelink-riscv.inc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tools/prelink-riscv.inc b/tools/prelink-riscv.inc index f2b5467f5b..d6a58929e9 100644 --- a/tools/prelink-riscv.inc +++ b/tools/prelink-riscv.inc @@ -30,7 +30,7 @@ #define cpu_to_target32 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 32) #define cpu_to_target64 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 64)
-static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr) +static void *get_offset_bonn(void *data, Elf_Phdr *phdrs, size_t phnum, Elf_Addr addr) { Elf_Phdr *p;
@@ -67,13 +67,13 @@ static void prelink_bonn(void *data) Elf_Rela *rela_dyn = NULL; size_t rela_count = 0; Elf_Sym *dynsym = NULL; - for (dyn = dyns;; ++dyn) { + for (dyn = dyns; ; ++dyn) { if (targetnn_to_cpu(dyn->d_tag) == DT_NULL) break; else if (targetnn_to_cpu(dyn->d_tag) == DT_RELA) rela_dyn = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr)); else if (targetnn_to_cpu(dyn->d_tag) == DT_RELASZ) - rela_count = targetnn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela); + rela_count = targetnn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela); else if (targetnn_to_cpu(dyn->d_tag) == DT_SYMTAB) dynsym = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
@@ -92,11 +92,11 @@ static void prelink_bonn(void *data) continue;
if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE) - *((uintnn_t*) buf) = r->r_addend; + *((uintnn_t*)buf) = r->r_addend; else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32) - *((uint32_t*) buf) = cpu_to_target32(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); + *((uint32_t*)buf) = cpu_to_target32(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64) - *((uint64_t*) buf) = cpu_to_target64(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); + *((uint64_t*)buf) = cpu_to_target64(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); } }

The codes forget to call munmap() to unmap the ELF image that was mapped by previous mmap().
Signed-off-by: Bin Meng bmeng@tinylab.org ---
tools/prelink-riscv.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/tools/prelink-riscv.c b/tools/prelink-riscv.c index b0467949eb..43d6412ee9 100644 --- a/tools/prelink-riscv.c +++ b/tools/prelink-riscv.c @@ -118,5 +118,7 @@ int main(int argc, const char *const *argv) prelink_le32(data); }
+ munmap(data, st.st_size); + return 0; }

On Fri, 31 Mar 2023 at 01:37, Bin Meng bmeng@tinylab.org wrote:
The codes forget to call munmap() to unmap the ELF image that was mapped by previous mmap().
Signed-off-by: Bin Meng bmeng@tinylab.org
tools/prelink-riscv.c | 2 ++ 1 file changed, 2 insertions(+)
Reviewed-by: Simon Glass sjg@chromium.org

The argv[2] is never used in prelink-riscv. Drop it.
Signed-off-by: Bin Meng bmeng@tinylab.org ---
Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile index ab93f29fc5..33e54bfa3d 100644 --- a/Makefile +++ b/Makefile @@ -1758,7 +1758,7 @@ ifeq ($(CONFIG_KALLSYMS),y) endif
ifeq ($(CONFIG_RISCV),y) - @tools/prelink-riscv $@ 0 + @tools/prelink-riscv $@ endif
quiet_cmd_sym ?= SYM $@

The codes currently skip the very first relocation entry, and have an inaccurate comment "skip first reserved entry" indicating that the first entry is reserved, but later it references the elements in the first relocation entry using a minus offset.
Change to use a positive offset so that there is no need to skip the first relocation entry.
Signed-off-by: Bin Meng bmeng@tinylab.org ---
arch/riscv/cpu/start.S | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 879bdc1803..c09d1cb412 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -302,17 +302,12 @@ fix_rela_dyn: add t1, t1, t6 /* t1 <- rela_dyn_start in RAM */ add t2, t2, t6 /* t2 <- rela_dyn_end in RAM */
-/* - * skip first reserved entry: address, type, addend - */ - j 10f - 6: - LREG t5, -(REGBYTES*2)(t1) /* t5 <-- relocation info:type */ + LREG t5, REGBYTES(t1) /* t5 <-- relocation info:type */ li t3, R_RISCV_RELATIVE /* reloc type R_RISCV_RELATIVE */ bne t5, t3, 8f /* skip non-RISCV_RELOC entries */ - LREG t3, -(REGBYTES*3)(t1) - LREG t5, -(REGBYTES)(t1) /* t5 <-- addend */ + LREG t3, 0(t1) + LREG t5, (REGBYTES * 2)(t1) /* t5 <-- addend */ add t5, t5, t6 /* t5 <-- location to fix up in RAM */ add t3, t3, t6 /* t3 <-- location to fix up in RAM */ SREG t5, 0(t3) @@ -328,19 +323,19 @@ fix_rela_dyn: li t3, RELOC_TYPE bne t5, t3, 10f /* skip non-addned entries */
- LREG t3, -(REGBYTES*3)(t1) + LREG t3, 0(t1) li t5, SYM_SIZE mul t0, t0, t5 add s5, t4, t0 - LREG t0, -(REGBYTES)(t1) /* t0 <-- addend */ + LREG t0, (REGBYTES * 2)(t1) /* t0 <-- addend */ LREG t5, REGBYTES(s5) add t5, t5, t0 add t5, t5, t6 /* t5 <-- location to fix up in RAM */ add t3, t3, t6 /* t3 <-- location to fix up in RAM */ SREG t5, 0(t3) 10: - addi t1, t1, (REGBYTES*3) - ble t1, t2, 6b + addi t1, t1, (REGBYTES * 3) + blt t1, t2, 6b
/* * trap update

U-Boot SPL is not relocable. Drop these relocation sections.
Signed-off-by: Bin Meng bmeng@tinylab.org ---
arch/riscv/cpu/u-boot-spl.lds | 25 ------------------------- 1 file changed, 25 deletions(-)
diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds index 993536302a..c3b4907905 100644 --- a/arch/riscv/cpu/u-boot-spl.lds +++ b/arch/riscv/cpu/u-boot-spl.lds @@ -32,14 +32,6 @@ SECTIONS } > .spl_mem . = ALIGN(4);
- .got : { - __got_start = .; - *(.got.plt) *(.got) - __got_end = .; - } > .spl_mem - - . = ALIGN(4); - __u_boot_list : { KEEP(*(SORT(__u_boot_list*))); } > .spl_mem @@ -54,23 +46,6 @@ SECTIONS
. = ALIGN(4);
- /DISCARD/ : { *(.rela.plt*) } - .rela.dyn : { - __rel_dyn_start = .; - *(.rela*) - __rel_dyn_end = .; - } > .spl_mem - - . = ALIGN(4); - - .dynsym : { - __dyn_sym_start = .; - *(.dynsym) - __dyn_sym_end = .; - } > .spl_mem - - . = ALIGN(4); - _end = .; _image_binary_end = .;

Some sections in the linker scripts are aligned to 4 bytes, which may cause misaligned exception on some platforms, e.g.: clearing the bss section on 64-bit hardware if __bss_start does not start from a naturally 8 bytes aligned address.
Signed-off-by: Bin Meng bmeng@tinylab.org
---
arch/riscv/cpu/u-boot-spl.lds | 2 +- arch/riscv/cpu/u-boot.lds | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds index c3b4907905..d1113a59aa 100644 --- a/arch/riscv/cpu/u-boot-spl.lds +++ b/arch/riscv/cpu/u-boot-spl.lds @@ -44,7 +44,7 @@ SECTIONS __binman_sym_end = .; } > .spl_mem
- . = ALIGN(4); + . = ALIGN(8);
_end = .; _image_binary_end = .; diff --git a/arch/riscv/cpu/u-boot.lds b/arch/riscv/cpu/u-boot.lds index 1c937aebee..15b5cbc585 100644 --- a/arch/riscv/cpu/u-boot.lds +++ b/arch/riscv/cpu/u-boot.lds @@ -57,7 +57,7 @@ SECTIONS __efi_runtime_rel_stop = .; }
- . = ALIGN(4); + . = ALIGN(8);
/DISCARD/ : { *(.rela.plt*) } .rela.dyn : { @@ -66,7 +66,7 @@ SECTIONS __rel_dyn_end = .; }
- . = ALIGN(4); + . = ALIGN(8);
.dynsym : { __dyn_sym_start = .; @@ -74,7 +74,7 @@ SECTIONS __dyn_sym_end = .; }
- . = ALIGN(4); + . = ALIGN(8);
_end = .;

On Thu, Mar 30, 2023 at 8:36 PM Bin Meng bmeng@tinylab.org wrote:
The __bss_start is the source end address hence load its address directly into register 't2' for optimization.
Signed-off-by: Bin Meng bmeng@tinylab.org
arch/riscv/cpu/start.S | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/riscv/cpu/start.S b/arch/riscv/cpu/start.S index 4687bca3c9..3c8344c345 100644 --- a/arch/riscv/cpu/start.S +++ b/arch/riscv/cpu/start.S @@ -283,9 +283,7 @@ stack_setup: beq t0, s4, clear_bss /* skip relocation */
mv t1, s4 /* t1 <- scratch for copy_loop */
la t3, __bss_start
sub t3, t3, t0 /* t3 <- __bss_start_ofs */
add t2, t0, t3 /* t2 <- source end address */
la t2, __bss_start /* t2 <- source end address */
copy_loop: LREG t5, 0(t0) --
Ping for this series?
participants (3)
-
Bin Meng
-
Bin Meng
-
Simon Glass