[PATCH] ARM: force linker to use PIC veneers

Nicolas Pitre nicolas.pitre at linaro.org
Tue Mar 24 09:42:04 PDT 2015


On Tue, 24 Mar 2015, Ard Biesheuvel wrote:

> When building a very large kernel, it is up to the linker to decide
> when and where to insert stubs to allow calls to functions that are
> out of range for the ordinary b/bl instructions.
> 
> However, since the kernel is built as a position dependent binary,
> these stubs (aka veneers) may contain absolute addresses, which will
> break such veneer assisted far calls performed with the MMU off.
> 
> For instance, the call from __enable_mmu() in the .head.text section
> to __turn_mmu_on() in the .idmap.text section may be turned into
> something like this:
> 
> c0008168 <__enable_mmu>:
> c0008168:       f020 0002       bic.w   r0, r0, #2
> c000816c:       f420 5080       bic.w   r0, r0, #4096
> c0008170:       f000 b846       b.w     c0008200 <____turn_mmu_on_veneer>
> [...]
> c0008200 <____turn_mmu_on_veneer>:
> c0008200:       4778            bx      pc
> c0008202:       46c0            nop
> c0008204:       e59fc000        ldr     ip, [pc]
> c0008208:       e12fff1c        bx      ip
> c000820c:       c13dfae1        teqgt   sp, r1, ror #21
> [...]
> c13dfae0 <__turn_mmu_on>:
> c13dfae0:       4600            mov     r0, r0
> [...]
> 
> After adding --pic-veneer to the LDFLAGS, the veneer is emitted like
> this instead:
> 
> c0008200 <____turn_mmu_on_veneer>:
> c0008200:       4778            bx      pc
> c0008202:       46c0            nop
> c0008204:       e59fc004        ldr     ip, [pc, #4]
> c0008208:       e08fc00c        add     ip, pc, ip
> c000820c:       e12fff1c        bx      ip
> c0008210:       013d7d31        teqeq   sp, r1, lsr sp
> c0008214:       00000000        andeq   r0, r0, r0
> 
> Note that this particular example is best addressed by moving
> .head.text and .idmap.text closer together, but this issue could
> potentially affect any code that needs to execute with the
> MMU off.
> 
> Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>

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

This is of no consequence when the kernel is still small enough not to 
require any veneers i.e. 99.99% of the time.  And, as I said, I prefer 
relying on the linker to insert those veneers as needed rather than 
using some unconditional far call macros.


> ---
>  arch/arm/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index eb7bb511f853..ae5b33527f32 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -13,7 +13,7 @@
>  # Ensure linker flags are correct
>  LDFLAGS		:=
>  
> -LDFLAGS_vmlinux	:=-p --no-undefined -X
> +LDFLAGS_vmlinux	:=-p --no-undefined -X --pic-veneer
>  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
>  LDFLAGS_vmlinux	+= --be8
>  LDFLAGS_MODULE	+= --be8
> -- 
> 1.8.3.2
> 
> 



More information about the linux-arm-kernel mailing list