[PATCH v2] ARM: Thumb-2: Add local symbols to work around gas behaviour

Nicolas Pitre nicolas.pitre at linaro.org
Thu Mar 17 12:54:25 EDT 2011


On Fri, 4 Mar 2011, Dave Martin wrote:

> All current versions of gas at the time of writing have issues
> fixing up pc-relative instructions which reference global symbols,
> due to the potential need to support symbol preemption.
> Even though symbol preemption is not relevant to the Linux kernel,
> there is no way to inform the tools of this, so we get the problem.
> 
> Most pc-relative forms in ARM, and all pc-relative forms in
> Thumb, will cause the assembler to fail with various fixup error
> messages when used to reference global symbols.
> 
> The legacy behaviour is for ADR and plain LDR instructions in ARM
> which reference global symbols to be fixed up silently with no
> relocation emitted.  This means that building the kernel in ARM
> currently works without problems, but this behaviour may be a bug.
> 
> After discussion with Richard Earnshaw, it seems that there is
> no single obvious remedy for this inconsistent behaviour,
> so there is not likely to be a comprehensive upstream fix for
> a while.
> 
> A workaround which should be valid for all past and all
> foreseeable future versions of gas is to express the need for
> a local fixup explicitly, by declaring a shadow local symbol
> for any global symbol which needs to be addressed using ADR
> or any pc-relative LDR variant.
> 
> This patch implements this workaround for the one part of the
> main kernel currently known to be affected.  The resulting code
> builds and works correctly in ARM and Thumb.
> 
> Similar fixes may be needed in mach-specific assembler.
> 
> Signed-off-by: Dave Martin <dave.martin at linaro.org>
> ---
> v2: Use .L* local symbols to avoid polluting the symbol table

Personal preference: I'd use .L_* which is a tad more readable.

Otherwise:

Acked-by: Nicolas Pitre <nicolas.pitre at linaro.org>


>  arch/arm/kernel/relocate_kernel.S |   12 ++++++++----
>  1 files changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
> index 9cf4cbf..ec0320c 100644
> --- a/arch/arm/kernel/relocate_kernel.S
> +++ b/arch/arm/kernel/relocate_kernel.S
> @@ -7,8 +7,8 @@
>  	.globl relocate_new_kernel
>  relocate_new_kernel:
>  
> -	ldr	r0,kexec_indirection_page
> -	ldr	r1,kexec_start_address
> +	ldr	r0,.Lkexec_indirection_page
> +	ldr	r1,.Lkexec_start_address
>  
>  	/*
>  	 * If there is no indirection page (we are doing crashdumps)
> @@ -55,27 +55,31 @@ relocate_new_kernel:
>  	/* Jump to relocated kernel */
>  	mov lr,r1
>  	mov r0,#0
> -	ldr r1,kexec_mach_type
> -	ldr r2,kexec_boot_atags
> +	ldr r1,.Lkexec_mach_type
> +	ldr r2,.Lkexec_boot_atags
>  	mov pc,lr
>  
>  	.align
>  
>  	.globl kexec_start_address
>  kexec_start_address:
> +.Lkexec_start_address:
>  	.long	0x0
>  
>  	.globl kexec_indirection_page
>  kexec_indirection_page:
> +.Lkexec_indirection_page:
>  	.long	0x0
>  
>  	.globl kexec_mach_type
>  kexec_mach_type:
> +.Lkexec_mach_type:
>  	.long	0x0
>  
>  	/* phy addr of the atags for the new kernel */
>  	.globl kexec_boot_atags
>  kexec_boot_atags:
> +.Lkexec_boot_atags:
>  	.long	0x0
>  
>  relocate_new_kernel_end:
> -- 
> 1.7.1
> 



More information about the linux-arm-kernel mailing list