Skip to content

Commit e05d4cd

Browse files
xry111chenhuacai
authored andcommitted
LoongArch: Add support for relocating the kernel with RELR relocation
RELR as a relocation packing format for relative relocations for reducing the size of relative relocation records. In a position independent executable there are often many relative relocation records, and our vmlinux is a PIE. The LLD linker (since 17.0.0) and the BFD linker (since 2.43) supports packing the relocations in the RELR format for LoongArch, with the flag -z pack-relative-relocs. Commits 5cf896f ("arm64: Add support for relocating the kernel with RELR relocations") and ccb2d17 ("Makefile: use -z pack-relative-relocs") have already added the framework to use RELR. We just need to wire it up and process the RELR relocation records in relocate_relative() in addition to the RELA relocation records. A ".p2align 3" directive is added to la_abs macro or the BFD linker cannot pack the relocation records against the .la_abs section (the ". = ALIGN(8);" directive in vmlinux.lds.S is too late in the linking process). With defconfig and CONFIG_RELR vmlinux.efi is 2.1 MiB (6%) smaller, and vmlinuz.efi (using gzip compression) is 384 KiB (2.8%) smaller. Link: https://groups.google.com/d/topic/generic-abi/bX460iggiKg Link: https://reviews.llvm.org/D138135#4531389 Link: https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=d89ecf33ab6d Signed-off-by: Xi Ruoyao <xry111@xry111.site> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent 0ad158e commit e05d4cd

File tree

5 files changed

+33
-0
lines changed

5 files changed

+33
-0
lines changed

arch/loongarch/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,6 +610,7 @@ config ARCH_HAS_GENERIC_CRASHKERNEL_RESERVATION
610610

611611
config RELOCATABLE
612612
bool "Relocatable kernel"
613+
select ARCH_HAS_RELR
613614
help
614615
This builds the kernel as a Position Independent Executable (PIE),
615616
which retains all relocation metadata required, so as to relocate

arch/loongarch/include/asm/asmmacro.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,7 @@
609609
lu32i.d \reg, 0
610610
lu52i.d \reg, \reg, 0
611611
.pushsection ".la_abs", "aw", %progbits
612+
.p2align 3
612613
.dword 766b
613614
.dword \sym
614615
.popsection

arch/loongarch/include/asm/setup.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ extern long __la_abs_end;
3434
extern long __rela_dyn_begin;
3535
extern long __rela_dyn_end;
3636

37+
#ifdef CONFIG_RELR
38+
extern long __relr_dyn_begin;
39+
extern long __relr_dyn_end;
40+
#endif
41+
3742
extern unsigned long __init relocate_kernel(void);
3843

3944
#endif

arch/loongarch/kernel/relocate.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,24 @@ static inline void __init relocate_relative(void)
3838
relocated_addr = (Elf64_Addr)RELOCATED(relocated_addr);
3939
*(Elf64_Addr *)RELOCATED(addr) = relocated_addr;
4040
}
41+
42+
#ifdef CONFIG_RELR
43+
u64 *addr = NULL;
44+
u64 *relr = (u64 *)&__relr_dyn_begin;
45+
u64 *relr_end = (u64 *)&__relr_dyn_end;
46+
47+
for ( ; relr < relr_end; relr++) {
48+
if ((*relr & 1) == 0) {
49+
addr = (u64 *)(*relr + reloc_offset);
50+
*addr++ += reloc_offset;
51+
} else {
52+
for (u64 *p = addr, r = *relr >> 1; r; p++, r >>= 1)
53+
if (r & 1)
54+
*p += reloc_offset;
55+
addr += 63;
56+
}
57+
}
58+
#endif
4159
}
4260

4361
static inline void __init relocate_absolute(long random_offset)

arch/loongarch/kernel/vmlinux.lds.S

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ SECTIONS
113113
__rela_dyn_end = .;
114114
}
115115

116+
#ifdef CONFIG_RELR
117+
.relr.dyn : ALIGN(8) {
118+
__relr_dyn_begin = .;
119+
*(.relr.dyn)
120+
__relr_dyn_end = .;
121+
}
122+
#endif
123+
116124
.data.rel : { *(.data.rel*) }
117125

118126
#ifdef CONFIG_RELOCATABLE

0 commit comments

Comments
 (0)