[PATCH 03/12] ARM: module: add support for place relative relocations

Nicolas Pitre nico at fluxnic.net
Mon Sep 14 09:35:41 EDT 2020


On Mon, 14 Sep 2020, Ard Biesheuvel wrote:

> When using the new adr_l/ldr_l/str_l macros to refer to external symbols
> from modules, the linker may emit place relative ELF relocations that
> need to be fixed up by the module loader. So add support for these.

Just wondering if that capability requirement should be added to the 
module signature somehow...?

Maybe not. The MODULE_ARCH_VERMAGIC definition only contains things that 
are configurable for a given build.


> 
> Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
> ---
>  arch/arm/include/asm/elf.h |  5 +++++
>  arch/arm/kernel/module.c   | 20 ++++++++++++++++++--
>  2 files changed, 23 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm/include/asm/elf.h b/arch/arm/include/asm/elf.h
> index b078d992414b..0ac62a54b73c 100644
> --- a/arch/arm/include/asm/elf.h
> +++ b/arch/arm/include/asm/elf.h
> @@ -51,6 +51,7 @@ typedef struct user_fp elf_fpregset_t;
>  #define R_ARM_NONE		0
>  #define R_ARM_PC24		1
>  #define R_ARM_ABS32		2
> +#define R_ARM_REL32		3
>  #define R_ARM_CALL		28
>  #define R_ARM_JUMP24		29
>  #define R_ARM_TARGET1		38
> @@ -58,11 +59,15 @@ typedef struct user_fp elf_fpregset_t;
>  #define R_ARM_PREL31		42
>  #define R_ARM_MOVW_ABS_NC	43
>  #define R_ARM_MOVT_ABS		44
> +#define R_ARM_MOVW_PREL_NC	45
> +#define R_ARM_MOVT_PREL		46
>  
>  #define R_ARM_THM_CALL		10
>  #define R_ARM_THM_JUMP24	30
>  #define R_ARM_THM_MOVW_ABS_NC	47
>  #define R_ARM_THM_MOVT_ABS	48
> +#define R_ARM_THM_MOVW_PREL_NC	49
> +#define R_ARM_THM_MOVT_PREL	50
>  
>  /*
>   * These are used to set parameters in the core dumps.
> diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
> index e15444b25ca0..beac45e89ba6 100644
> --- a/arch/arm/kernel/module.c
> +++ b/arch/arm/kernel/module.c
> @@ -185,14 +185,24 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
>  			*(u32 *)loc |= offset & 0x7fffffff;
>  			break;
>  
> +		case R_ARM_REL32:
> +			*(u32 *)loc += sym->st_value - loc;
> +			break;
> +
>  		case R_ARM_MOVW_ABS_NC:
>  		case R_ARM_MOVT_ABS:
> +		case R_ARM_MOVW_PREL_NC:
> +		case R_ARM_MOVT_PREL:
>  			offset = tmp = __mem_to_opcode_arm(*(u32 *)loc);
>  			offset = ((offset & 0xf0000) >> 4) | (offset & 0xfff);
>  			offset = (offset ^ 0x8000) - 0x8000;
>  
>  			offset += sym->st_value;
> -			if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS)
> +			if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_PREL ||
> +			    ELF32_R_TYPE(rel->r_info) == R_ARM_MOVW_PREL_NC)
> +				offset -= loc;
> +			if (ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_ABS ||
> +			    ELF32_R_TYPE(rel->r_info) == R_ARM_MOVT_PREL)
>  				offset >>= 16;
>  
>  			tmp &= 0xfff0f000;
> @@ -283,6 +293,8 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
>  
>  		case R_ARM_THM_MOVW_ABS_NC:
>  		case R_ARM_THM_MOVT_ABS:
> +		case R_ARM_THM_MOVW_PREL_NC:
> +		case R_ARM_THM_MOVT_PREL:
>  			upper = __mem_to_opcode_thumb16(*(u16 *)loc);
>  			lower = __mem_to_opcode_thumb16(*(u16 *)(loc + 2));
>  
> @@ -302,7 +314,11 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
>  			offset = (offset ^ 0x8000) - 0x8000;
>  			offset += sym->st_value;
>  
> -			if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS)
> +			if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_PREL ||
> +			    ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVW_PREL_NC)
> +				offset -= loc;
> +			if (ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_ABS ||
> +			    ELF32_R_TYPE(rel->r_info) == R_ARM_THM_MOVT_PREL)
>  				offset >>= 16;
>  
>  			upper = (u16)((upper & 0xfbf0) |
> -- 
> 2.17.1
> 
> 



More information about the linux-arm-kernel mailing list