* [PATCH 1/2] ARM: cpu: common: skip R_ARM_NONE relocations @ 2026-01-06 8:16 Ahmad Fatoum 2026-01-06 8:16 ` [PATCH 2/2] ARM: cpu: common: define generic relocate_image Ahmad Fatoum 2026-01-06 13:18 ` [PATCH 1/2] ARM: cpu: common: skip R_ARM_NONE relocations Sascha Hauer 0 siblings, 2 replies; 5+ messages in thread From: Ahmad Fatoum @ 2026-01-06 8:16 UTC (permalink / raw) To: barebox; +Cc: Ahmad Fatoum Relocations may be turned into no-op in place by strip running on an executable by having their type set to 0 (R_ARM_NONE). This can happen with the incoming ELF loading in PBL support, so teach relocate_to_current_adr() to skip these no-op relocation entries. Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org> --- arch/arm/cpu/common.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c index 339ef2db2534..5b65b0745b98 100644 --- a/arch/arm/cpu/common.c +++ b/arch/arm/cpu/common.c @@ -36,6 +36,7 @@ void sync_caches_for_execution(void) arm_early_mmu_cache_flush(); } +#define R_ARM_NONE 0 #define R_ARM_RELATIVE 23 #define R_AARCH64_RELATIVE 1027 @@ -78,14 +79,19 @@ void __prereloc relocate_to_current_adr(void) #if defined(CONFIG_CPU_64) while (dstart < dend) { struct elf64_rela *rel = dstart; + unsigned long *fixup; - if (ELF64_R_TYPE(rel->r_info) == R_AARCH64_RELATIVE) { - unsigned long *fixup = (unsigned long *)(rel->r_offset + offset); + switch(ELF64_R_TYPE(rel->r_info)) { + case R_AARCH64_RELATIVE: + fixup = (unsigned long *)(rel->r_offset + offset); *fixup = rel->r_addend + offset; rel->r_addend += offset; rel->r_offset += offset; - } else { + break; + case R_ARM_NONE: + break; + default: putc_ll('>'); puthex_ll(rel->r_info); putc_ll(' '); @@ -104,20 +110,26 @@ void __prereloc relocate_to_current_adr(void) while (dstart < dend) { struct elf32_rel *rel = dstart; + unsigned long r, *fixup; - if (ELF32_R_TYPE(rel->r_info) == R_ARM_RELATIVE) { - unsigned long *fixup = (unsigned long *)(rel->r_offset + offset); + switch (ELF32_R_TYPE(rel->r_info)) { + case R_ARM_RELATIVE: + fixup = (unsigned long *)(rel->r_offset + offset); *fixup = *fixup + offset; rel->r_offset += offset; - } else if (ELF32_R_TYPE(rel->r_info) == R_ARM_ABS32) { - unsigned long r = dynsym[ELF32_R_SYM(rel->r_info) * 4 + 1]; - unsigned long *fixup = (unsigned long *)(rel->r_offset + offset); + break; + case R_ARM_ABS32: + r = dynsym[ELF32_R_SYM(rel->r_info) * 4 + 1]; + fixup = (unsigned long *)(rel->r_offset + offset); *fixup = *fixup + r + offset; rel->r_offset += offset; - } else { + break; + case R_ARM_NONE: + break; + default: putc_ll('>'); puthex_ll(rel->r_info); putc_ll(' '); -- 2.47.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 2/2] ARM: cpu: common: define generic relocate_image 2026-01-06 8:16 [PATCH 1/2] ARM: cpu: common: skip R_ARM_NONE relocations Ahmad Fatoum @ 2026-01-06 8:16 ` Ahmad Fatoum 2026-01-06 9:16 ` Sascha Hauer 2026-01-06 11:43 ` Ahmad Fatoum 2026-01-06 13:18 ` [PATCH 1/2] ARM: cpu: common: skip R_ARM_NONE relocations Sascha Hauer 1 sibling, 2 replies; 5+ messages in thread From: Ahmad Fatoum @ 2026-01-06 8:16 UTC (permalink / raw) To: barebox; +Cc: Ahmad Fatoum For use by the ELF loader in PBL to relocate barebox proper, export a new relocate_image capable of relocating barebox and implement relocate_to_current_adr() in terms of it. When doing ELF loading, the PT_DYNAMIC segment will contain the info needed to derive the arguments for relocate_image(): - dstart: DT_REL /DT_RELA - dend: DT_RELSZ/DT_RELASZ - dynsym: DT_SYMTAB dynend is optional and could in theory be generated by looking at DT_HASH or DT_GNU_HASH, but it's not required. Best guess is that the zeroing is there just to signify that we don't need this data anymore. Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org> --- arch/arm/cpu/common.c | 34 +++++++++++++++------------------- arch/arm/include/asm/reloc.h | 3 +++ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c index 5b65b0745b98..f4f3f8f6325b 100644 --- a/arch/arm/cpu/common.c +++ b/arch/arm/cpu/common.c @@ -60,22 +60,10 @@ void pbl_barebox_break(void) /* * relocate binary to the currently running address */ -void __prereloc relocate_to_current_adr(void) +void __prereloc relocate_image(unsigned long offset, + void *dstart, void *dend, + long *dynsym, long *dynend) { - unsigned long offset; - unsigned long __maybe_unused *dynsym, *dynend; - void *dstart, *dend; - - /* Get offset between linked address and runtime address */ - offset = get_runtime_offset(); - - /* - * We have yet to relocate, so using runtime_address - * to compute the relocated address - */ - dstart = runtime_address(__rel_dyn_start); - dend = runtime_address(__rel_dyn_end); - #if defined(CONFIG_CPU_64) while (dstart < dend) { struct elf64_rela *rel = dstart; @@ -105,8 +93,6 @@ void __prereloc relocate_to_current_adr(void) dstart += sizeof(*rel); } #elif defined(CONFIG_CPU_32) - dynsym = runtime_address(__dynsym_start); - dynend = runtime_address(__dynsym_end); while (dstart < dend) { struct elf32_rel *rel = dstart; @@ -141,10 +127,21 @@ void __prereloc relocate_to_current_adr(void) dstart += sizeof(*rel); } - __memset(dynsym, 0, (unsigned long)dynend - (unsigned long)dynsym); + /* Optional: not required for correctness */ + if (dynend) + __memset(dynsym, 0, (unsigned long)dynend - (unsigned long)dynsym); #else #error "Architecture not specified" #endif +} + +void __prereloc relocate_to_current_adr(void) +{ + relocate_image(get_runtime_offset(), + runtime_address(__rel_dyn_start), + runtime_address(__rel_dyn_end), + runtime_address(__dynsym_start), + runtime_address(__dynsym_end)); sync_caches_for_execution(); } @@ -196,4 +193,3 @@ void print_pbl_mem_layout(ulong membase, ulong endmem, ulong barebox_base) printf("membase = 0x%08lx+0x%08lx\n", membase, endmem - membase); } - diff --git a/arch/arm/include/asm/reloc.h b/arch/arm/include/asm/reloc.h index 2d7411ab5284..62c07932fad4 100644 --- a/arch/arm/include/asm/reloc.h +++ b/arch/arm/include/asm/reloc.h @@ -30,6 +30,9 @@ static inline __prereloc unsigned long global_variable_offset(void) } #define global_variable_offset() global_variable_offset() +void relocate_image(unsigned long offset, + void *dstart, void *dend, + long *dynsym, long *dynend); void relocate_to_current_adr(void); void relocate_to_adr(unsigned long target); void relocate_to_adr_full(unsigned long target); -- 2.47.3 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] ARM: cpu: common: define generic relocate_image 2026-01-06 8:16 ` [PATCH 2/2] ARM: cpu: common: define generic relocate_image Ahmad Fatoum @ 2026-01-06 9:16 ` Sascha Hauer 2026-01-06 11:43 ` Ahmad Fatoum 1 sibling, 0 replies; 5+ messages in thread From: Sascha Hauer @ 2026-01-06 9:16 UTC (permalink / raw) To: Ahmad Fatoum; +Cc: barebox On Tue, Jan 06, 2026 at 09:16:57AM +0100, Ahmad Fatoum wrote: > For use by the ELF loader in PBL to relocate barebox proper, export a > new relocate_image capable of relocating barebox and implement > relocate_to_current_adr() in terms of it. > > When doing ELF loading, the PT_DYNAMIC segment will contain the info > needed to derive the arguments for relocate_image(): > > - dstart: DT_REL /DT_RELA > - dend: DT_RELSZ/DT_RELASZ > - dynsym: DT_SYMTAB > > dynend is optional and could in theory be generated by looking at > DT_HASH or DT_GNU_HASH, but it's not required. Best guess is that the > zeroing is there just to signify that we don't need this data anymore. > > Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org> > --- > arch/arm/cpu/common.c | 34 +++++++++++++++------------------- > arch/arm/include/asm/reloc.h | 3 +++ > 2 files changed, 18 insertions(+), 19 deletions(-) > > diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c > index 5b65b0745b98..f4f3f8f6325b 100644 > --- a/arch/arm/cpu/common.c > +++ b/arch/arm/cpu/common.c > @@ -60,22 +60,10 @@ void pbl_barebox_break(void) > /* > * relocate binary to the currently running address > */ > -void __prereloc relocate_to_current_adr(void) > +void __prereloc relocate_image(unsigned long offset, > + void *dstart, void *dend, > + long *dynsym, long *dynend) As relocate_image() now contains two entirely separate implementations for ARM32 and ARM64, should we move it to arch/arm/lib[32|64]/ ? > { > - unsigned long offset; > - unsigned long __maybe_unused *dynsym, *dynend; > - void *dstart, *dend; > - > - /* Get offset between linked address and runtime address */ > - offset = get_runtime_offset(); > - > - /* > - * We have yet to relocate, so using runtime_address > - * to compute the relocated address > - */ > - dstart = runtime_address(__rel_dyn_start); > - dend = runtime_address(__rel_dyn_end); > - > #if defined(CONFIG_CPU_64) > while (dstart < dend) { > struct elf64_rela *rel = dstart; > @@ -105,8 +93,6 @@ void __prereloc relocate_to_current_adr(void) > dstart += sizeof(*rel); > } > #elif defined(CONFIG_CPU_32) > - dynsym = runtime_address(__dynsym_start); > - dynend = runtime_address(__dynsym_end); > > while (dstart < dend) { > struct elf32_rel *rel = dstart; > @@ -141,10 +127,21 @@ void __prereloc relocate_to_current_adr(void) > dstart += sizeof(*rel); > } > > - __memset(dynsym, 0, (unsigned long)dynend - (unsigned long)dynsym); > + /* Optional: not required for correctness */ > + if (dynend) > + __memset(dynsym, 0, (unsigned long)dynend - (unsigned long)dynsym); The purpose of this memset is that we can call relocate_to_current_adr() multiple times on the same binary. This happens when relocate_to_current_adr() is called in the board code and then again in uncompress.c. I think in this particular case we could just early return above when offset == 0, but I think there are (were?) some cases where the same binary is moved multiple times. Sascha -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] ARM: cpu: common: define generic relocate_image 2026-01-06 8:16 ` [PATCH 2/2] ARM: cpu: common: define generic relocate_image Ahmad Fatoum 2026-01-06 9:16 ` Sascha Hauer @ 2026-01-06 11:43 ` Ahmad Fatoum 1 sibling, 0 replies; 5+ messages in thread From: Ahmad Fatoum @ 2026-01-06 11:43 UTC (permalink / raw) To: Ahmad Fatoum, barebox Hi, On 1/6/26 9:16 AM, Ahmad Fatoum wrote: > - __memset(dynsym, 0, (unsigned long)dynend - (unsigned long)dynsym); > + /* Optional: not required for correctness */ > + if (dynend) > + __memset(dynsym, 0, (unsigned long)dynend - (unsigned long)dynsym); Unexpected revelation: We don't have any R_ARM_ABS32 relocations any longer. Maybe because ARM32 is now always relocatable? This will allow us to simplify some things. Cheers, Ahmad > #else > #error "Architecture not specified" > #endif > +} > + > +void __prereloc relocate_to_current_adr(void) > +{ > + relocate_image(get_runtime_offset(), > + runtime_address(__rel_dyn_start), > + runtime_address(__rel_dyn_end), > + runtime_address(__dynsym_start), > + runtime_address(__dynsym_end)); > > sync_caches_for_execution(); > } > @@ -196,4 +193,3 @@ void print_pbl_mem_layout(ulong membase, ulong endmem, ulong barebox_base) > printf("membase = 0x%08lx+0x%08lx\n", > membase, endmem - membase); > } > - > diff --git a/arch/arm/include/asm/reloc.h b/arch/arm/include/asm/reloc.h > index 2d7411ab5284..62c07932fad4 100644 > --- a/arch/arm/include/asm/reloc.h > +++ b/arch/arm/include/asm/reloc.h > @@ -30,6 +30,9 @@ static inline __prereloc unsigned long global_variable_offset(void) > } > #define global_variable_offset() global_variable_offset() > > +void relocate_image(unsigned long offset, > + void *dstart, void *dend, > + long *dynsym, long *dynend); > void relocate_to_current_adr(void); > void relocate_to_adr(unsigned long target); > void relocate_to_adr_full(unsigned long target); -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH 1/2] ARM: cpu: common: skip R_ARM_NONE relocations 2026-01-06 8:16 [PATCH 1/2] ARM: cpu: common: skip R_ARM_NONE relocations Ahmad Fatoum 2026-01-06 8:16 ` [PATCH 2/2] ARM: cpu: common: define generic relocate_image Ahmad Fatoum @ 2026-01-06 13:18 ` Sascha Hauer 1 sibling, 0 replies; 5+ messages in thread From: Sascha Hauer @ 2026-01-06 13:18 UTC (permalink / raw) To: barebox, Ahmad Fatoum On Tue, 06 Jan 2026 09:16:56 +0100, Ahmad Fatoum wrote: > Relocations may be turned into no-op in place by strip running on an > executable by having their type set to 0 (R_ARM_NONE). > > This can happen with the incoming ELF loading in PBL support, so teach > relocate_to_current_adr() to skip these no-op relocation entries. > > > [...] Applied, thanks! [1/2] ARM: cpu: common: skip R_ARM_NONE relocations https://git.pengutronix.de/cgit/barebox/commit/?id=9ef816e176d9 (link may not be stable) [2/2] ARM: cpu: common: define generic relocate_image https://git.pengutronix.de/cgit/barebox/commit/?id=d7ee5518c5cc (link may not be stable) Best regards, -- Sascha Hauer <s.hauer@pengutronix.de> ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-01-06 13:18 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-01-06 8:16 [PATCH 1/2] ARM: cpu: common: skip R_ARM_NONE relocations Ahmad Fatoum 2026-01-06 8:16 ` [PATCH 2/2] ARM: cpu: common: define generic relocate_image Ahmad Fatoum 2026-01-06 9:16 ` Sascha Hauer 2026-01-06 11:43 ` Ahmad Fatoum 2026-01-06 13:18 ` [PATCH 1/2] ARM: cpu: common: skip R_ARM_NONE relocations Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox