diff mbox series

[2/2] ARM: Wrap '--pic-veneer' with ld-option

Message ID 20181205014213.943-2-natechancellor@gmail.com (mailing list archive)
State New, archived
Headers show
Series [1/2] ARM: Remove '-p' from LDFLAGS | expand

Commit Message

Nathan Chancellor Dec. 5, 2018, 1:42 a.m. UTC
This flag is not supported by lld:

    ld.lld: error: unknown argument: --pic-veneer

Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
---
 arch/arm/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Ard Biesheuvel Dec. 5, 2018, 7:37 a.m. UTC | #1
On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
>
> This flag is not supported by lld:
>
>     ld.lld: error: unknown argument: --pic-veneer
>
> Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>

Hi Nate,

Does this mean ld.lld is guaranteed to produce position independent
veneers if you build kernels that are bigger than the typical range of
a relative branch?

> ---
>  arch/arm/Makefile | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index e2a0baf36766..4fab2aa29570 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -10,7 +10,7 @@
>  #
>  # Copyright (C) 1995-2001 by Russell King
>
> -LDFLAGS_vmlinux        := --no-undefined -X --pic-veneer
> +LDFLAGS_vmlinux        := --no-undefined -X $(call ld-option,--pic-veneer)
>  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
>  LDFLAGS_vmlinux        += --be8
>  KBUILD_LDFLAGS_MODULE  += --be8
> --
> 2.20.0.rc1
>
Nathan Chancellor Dec. 5, 2018, 8:06 a.m. UTC | #2
On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >
> > This flag is not supported by lld:
> >
> >     ld.lld: error: unknown argument: --pic-veneer
> >
> > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> 
> Hi Nate,
> 
> Does this mean ld.lld is guaranteed to produce position independent
> veneers if you build kernels that are bigger than the typical range of
> a relative branch?
> 

Hi Ard,

Honestly, I'm not quite sure. I saw your commit that introduced this
flag and I wasn't quite sure what to make of it for lld. What
configuration would I use to verify and what would I check for?

Additionally, I have filed an LLVM bug for the lld developers to
check and see if this is a flag they should support:

https://bugs.llvm.org/show_bug.cgi?id=39886

Thanks for the quick reply,
Nathan

> > ---
> >  arch/arm/Makefile | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > index e2a0baf36766..4fab2aa29570 100644
> > --- a/arch/arm/Makefile
> > +++ b/arch/arm/Makefile
> > @@ -10,7 +10,7 @@
> >  #
> >  # Copyright (C) 1995-2001 by Russell King
> >
> > -LDFLAGS_vmlinux        := --no-undefined -X --pic-veneer
> > +LDFLAGS_vmlinux        := --no-undefined -X $(call ld-option,--pic-veneer)
> >  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
> >  LDFLAGS_vmlinux        += --be8
> >  KBUILD_LDFLAGS_MODULE  += --be8
> > --
> > 2.20.0.rc1
> >
Ard Biesheuvel Dec. 5, 2018, 8:09 a.m. UTC | #3
(+ Arnd)

On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
>
> On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > >
> > > This flag is not supported by lld:
> > >
> > >     ld.lld: error: unknown argument: --pic-veneer
> > >
> > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> >
> > Hi Nate,
> >
> > Does this mean ld.lld is guaranteed to produce position independent
> > veneers if you build kernels that are bigger than the typical range of
> > a relative branch?
> >
>
> Hi Ard,
>
> Honestly, I'm not quite sure. I saw your commit that introduced this
> flag and I wasn't quite sure what to make of it for lld. What
> configuration would I use to verify and what would I check for?
>

Try building allyesconfig, and check the resulting binary for veneers
(which have 'veneer' in the symbol name, at least when ld.bfd emits
them). These veneers should not take the [virtual] address of the
branch target directly, but take a PC relative offset (as in the
example in the commit log of that patch you are referring to)

> Additionally, I have filed an LLVM bug for the lld developers to
> check and see if this is a flag they should support:
>
> https://bugs.llvm.org/show_bug.cgi?id=39886
>
> Thanks for the quick reply,
> Nathan
>
> > > ---
> > >  arch/arm/Makefile | 2 +-
> > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > > index e2a0baf36766..4fab2aa29570 100644
> > > --- a/arch/arm/Makefile
> > > +++ b/arch/arm/Makefile
> > > @@ -10,7 +10,7 @@
> > >  #
> > >  # Copyright (C) 1995-2001 by Russell King
> > >
> > > -LDFLAGS_vmlinux        := --no-undefined -X --pic-veneer
> > > +LDFLAGS_vmlinux        := --no-undefined -X $(call ld-option,--pic-veneer)
> > >  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
> > >  LDFLAGS_vmlinux        += --be8
> > >  KBUILD_LDFLAGS_MODULE  += --be8
> > > --
> > > 2.20.0.rc1
> > >
Nick Desaulniers Dec. 5, 2018, 6:21 p.m. UTC | #4
On Wed, Dec 5, 2018 at 12:10 AM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
>
> (+ Arnd)
>
> On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >
> > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > >
> > > > This flag is not supported by lld:
> > > >
> > > >     ld.lld: error: unknown argument: --pic-veneer
> > > >
> > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> > >
> > > Hi Nate,
> > >
> > > Does this mean ld.lld is guaranteed to produce position independent
> > > veneers if you build kernels that are bigger than the typical range of
> > > a relative branch?

(+ Peter) who might be able to answer this.

> > >
> >
> > Hi Ard,
> >
> > Honestly, I'm not quite sure. I saw your commit that introduced this
> > flag and I wasn't quite sure what to make of it for lld. What
> > configuration would I use to verify and what would I check for?
> >
>
> Try building allyesconfig, and check the resulting binary for veneers
> (which have 'veneer' in the symbol name, at least when ld.bfd emits
> them). These veneers should not take the [virtual] address of the
> branch target directly, but take a PC relative offset (as in the
> example in the commit log of that patch you are referring to)

Not sure clang can compile an arm32 allyesconfig (haven't tried
personally, yet, TODO), but we could try gcc+lld.

>
> > Additionally, I have filed an LLVM bug for the lld developers to
> > check and see if this is a flag they should support:
> >
> > https://bugs.llvm.org/show_bug.cgi?id=39886
> >
> > Thanks for the quick reply,
> > Nathan
> >
> > > > ---
> > > >  arch/arm/Makefile | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > > > index e2a0baf36766..4fab2aa29570 100644
> > > > --- a/arch/arm/Makefile
> > > > +++ b/arch/arm/Makefile
> > > > @@ -10,7 +10,7 @@
> > > >  #
> > > >  # Copyright (C) 1995-2001 by Russell King
> > > >
> > > > -LDFLAGS_vmlinux        := --no-undefined -X --pic-veneer
> > > > +LDFLAGS_vmlinux        := --no-undefined -X $(call ld-option,--pic-veneer)
> > > >  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
> > > >  LDFLAGS_vmlinux        += --be8
> > > >  KBUILD_LDFLAGS_MODULE  += --be8
> > > > --
> > > > 2.20.0.rc1
> > > >
Nathan Chancellor Dec. 5, 2018, 6:36 p.m. UTC | #5
On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
> (+ Arnd)
> 
> On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >
> > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > >
> > > > This flag is not supported by lld:
> > > >
> > > >     ld.lld: error: unknown argument: --pic-veneer
> > > >
> > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> > >
> > > Hi Nate,
> > >
> > > Does this mean ld.lld is guaranteed to produce position independent
> > > veneers if you build kernels that are bigger than the typical range of
> > > a relative branch?
> > >
> >
> > Hi Ard,
> >
> > Honestly, I'm not quite sure. I saw your commit that introduced this
> > flag and I wasn't quite sure what to make of it for lld. What
> > configuration would I use to verify and what would I check for?
> >
> 
> Try building allyesconfig, and check the resulting binary for veneers
> (which have 'veneer' in the symbol name, at least when ld.bfd emits
> them). These veneers should not take the [virtual] address of the
> branch target directly, but take a PC relative offset (as in the
> example in the commit log of that patch you are referring to)
> 

Alright, compiling with allyesconfig is a little rough at the moment
(bug reports I will file in due time) but I was able to do it. Here's
the disassembly specifically for the functions you had in your commit,
my assembly knowledge is pretty much non-existent unfortunately so I am
not sure what to make of it (it doesn't look like there is a virtual
address for pc in that mix?). I am happy to provide any more information
that is needed.

c03030cc <__enable_mmu>:
c03030cc:	e3c00002 	bic	r0, r0, #2
c03030d0:	e3c00b02 	bic	r0, r0, #2048	; 0x800
c03030d4:	e3c00a01 	bic	r0, r0, #4096	; 0x1000
c03030d8:	e3a05051 	mov	r5, #81	; 0x51
c03030dc:	ee035f10 	mcr	15, 0, r5, cr3, cr0, {0}
c03030e0:	ee024f10 	mcr	15, 0, r4, cr2, cr0, {0}
c03030e4:	eafff3c5 	b	c0300000 <__turn_mmu_on>
c03030e8:	e320f000 	nop	{0}
c03030ec:	e320f000 	nop	{0}
c03030f0:	e320f000 	nop	{0}
c03030f4:	e320f000 	nop	{0}
c03030f8:	e320f000 	nop	{0}
c03030fc:	e320f000 	nop	{0}

c0300000 <__turn_mmu_on>:
c0300000:	e1a00000 	nop			; (mov r0, r0)
c0300004:	ee070f95 	mcr	15, 0, r0, cr7, cr5, {4}
c0300008:	ee010f10 	mcr	15, 0, r0, cr1, cr0, {0}
c030000c:	ee103f10 	mrc	15, 0, r3, cr0, cr0, {0}
c0300010:	ee070f95 	mcr	15, 0, r0, cr7, cr5, {4}
c0300014:	e1a03003 	mov	r3, r3
c0300018:	e1a0300d 	mov	r3, sp
c030001c:	e1a0f003 	mov	pc, r3

Thanks,
Nathan

> > Additionally, I have filed an LLVM bug for the lld developers to
> > check and see if this is a flag they should support:
> >
> > https://bugs.llvm.org/show_bug.cgi?id=39886
> >
> > Thanks for the quick reply,
> > Nathan
> >
> > > > ---
> > > >  arch/arm/Makefile | 2 +-
> > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > >
> > > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > > > index e2a0baf36766..4fab2aa29570 100644
> > > > --- a/arch/arm/Makefile
> > > > +++ b/arch/arm/Makefile
> > > > @@ -10,7 +10,7 @@
> > > >  #
> > > >  # Copyright (C) 1995-2001 by Russell King
> > > >
> > > > -LDFLAGS_vmlinux        := --no-undefined -X --pic-veneer
> > > > +LDFLAGS_vmlinux        := --no-undefined -X $(call ld-option,--pic-veneer)
> > > >  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
> > > >  LDFLAGS_vmlinux        += --be8
> > > >  KBUILD_LDFLAGS_MODULE  += --be8
> > > > --
> > > > 2.20.0.rc1
> > > >
Ard Biesheuvel Dec. 5, 2018, 6:39 p.m. UTC | #6
On Wed, 5 Dec 2018 at 19:36, Nathan Chancellor <natechancellor@gmail.com> wrote:
>
> On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
> > (+ Arnd)
> >
> > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > >
> > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > > >
> > > > > This flag is not supported by lld:
> > > > >
> > > > >     ld.lld: error: unknown argument: --pic-veneer
> > > > >
> > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> > > >
> > > > Hi Nate,
> > > >
> > > > Does this mean ld.lld is guaranteed to produce position independent
> > > > veneers if you build kernels that are bigger than the typical range of
> > > > a relative branch?
> > > >
> > >
> > > Hi Ard,
> > >
> > > Honestly, I'm not quite sure. I saw your commit that introduced this
> > > flag and I wasn't quite sure what to make of it for lld. What
> > > configuration would I use to verify and what would I check for?
> > >
> >
> > Try building allyesconfig, and check the resulting binary for veneers
> > (which have 'veneer' in the symbol name, at least when ld.bfd emits
> > them). These veneers should not take the [virtual] address of the
> > branch target directly, but take a PC relative offset (as in the
> > example in the commit log of that patch you are referring to)
> >
>
> Alright, compiling with allyesconfig is a little rough at the moment
> (bug reports I will file in due time) but I was able to do it. Here's
> the disassembly specifically for the functions you had in your commit,
> my assembly knowledge is pretty much non-existent unfortunately so I am
> not sure what to make of it (it doesn't look like there is a virtual
> address for pc in that mix?). I am happy to provide any more information
> that is needed.
>
> c03030cc <__enable_mmu>:
> c03030cc:       e3c00002        bic     r0, r0, #2
> c03030d0:       e3c00b02        bic     r0, r0, #2048   ; 0x800
> c03030d4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
> c03030d8:       e3a05051        mov     r5, #81 ; 0x51
> c03030dc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
> c03030e0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
> c03030e4:       eafff3c5        b       c0300000 <__turn_mmu_on>
> c03030e8:       e320f000        nop     {0}
> c03030ec:       e320f000        nop     {0}
> c03030f0:       e320f000        nop     {0}
> c03030f4:       e320f000        nop     {0}
> c03030f8:       e320f000        nop     {0}
> c03030fc:       e320f000        nop     {0}
>
> c0300000 <__turn_mmu_on>:
> c0300000:       e1a00000        nop                     ; (mov r0, r0)
> c0300004:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> c0300008:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
> c030000c:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}
> c0300010:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> c0300014:       e1a03003        mov     r3, r3
> c0300018:       e1a0300d        mov     r3, sp
> c030001c:       e1a0f003        mov     pc, r3
>

Thanks Nate.

So these functions no longer appear to reside far away from each
other, so there no veneer has been emitted.

What we're looking for are veneers, i.e., snippets inserted by the
linker that serve as a trampoline so a branch target that is far away
can be reached.

If no symbols exist with 'veneer' in their name *, it might make sense
to rebuild the kernel as Thumb2, which has a branching range of only 8
MB (as opposed to 16 MB for ARM mode)

* I have no idea whether lld names its veneers like this, or even at all
Nick Desaulniers Dec. 5, 2018, 6:40 p.m. UTC | #7
On Wed, Dec 5, 2018 at 10:36 AM Nathan Chancellor
<natechancellor@gmail.com> wrote:
>
> On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
> > (+ Arnd)
> >
> > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > >
> > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > > >
> > > > > This flag is not supported by lld:
> > > > >
> > > > >     ld.lld: error: unknown argument: --pic-veneer
> > > > >
> > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> > > >
> > > > Hi Nate,
> > > >
> > > > Does this mean ld.lld is guaranteed to produce position independent
> > > > veneers if you build kernels that are bigger than the typical range of
> > > > a relative branch?
> > > >
> > >
> > > Hi Ard,
> > >
> > > Honestly, I'm not quite sure. I saw your commit that introduced this
> > > flag and I wasn't quite sure what to make of it for lld. What
> > > configuration would I use to verify and what would I check for?
> > >
> >
> > Try building allyesconfig, and check the resulting binary for veneers
> > (which have 'veneer' in the symbol name, at least when ld.bfd emits
> > them). These veneers should not take the [virtual] address of the
> > branch target directly, but take a PC relative offset (as in the
> > example in the commit log of that patch you are referring to)
> >
>
> Alright, compiling with allyesconfig is a little rough at the moment
> (bug reports I will file in due time) but I was able to do it. Here's
> the disassembly specifically for the functions you had in your commit,
> my assembly knowledge is pretty much non-existent unfortunately so I am
> not sure what to make of it (it doesn't look like there is a virtual
> address for pc in that mix?). I am happy to provide any more information
> that is needed.

Nathan,
Thanks for getting a build working!  I think Ard is looking for the
presence of symbols with `veneer` in the name.

Something like `llvm-objdump -t vmlinux | grep veneer` or `llvm-nm
vmlinux | grep veneer` should tell you if such symbols exist.

If they do, Ard was then looking for the disassembly of those labels
(like you provided for __enable_mmu/__turn_mmu_on).

>
> c03030cc <__enable_mmu>:
> c03030cc:       e3c00002        bic     r0, r0, #2
> c03030d0:       e3c00b02        bic     r0, r0, #2048   ; 0x800
> c03030d4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
> c03030d8:       e3a05051        mov     r5, #81 ; 0x51
> c03030dc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
> c03030e0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
> c03030e4:       eafff3c5        b       c0300000 <__turn_mmu_on>
> c03030e8:       e320f000        nop     {0}
> c03030ec:       e320f000        nop     {0}
> c03030f0:       e320f000        nop     {0}
> c03030f4:       e320f000        nop     {0}
> c03030f8:       e320f000        nop     {0}
> c03030fc:       e320f000        nop     {0}
>
> c0300000 <__turn_mmu_on>:
> c0300000:       e1a00000        nop                     ; (mov r0, r0)
> c0300004:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> c0300008:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
> c030000c:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}
> c0300010:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> c0300014:       e1a03003        mov     r3, r3
> c0300018:       e1a0300d        mov     r3, sp
> c030001c:       e1a0f003        mov     pc, r3
>
> Thanks,
> Nathan
>
> > > Additionally, I have filed an LLVM bug for the lld developers to
> > > check and see if this is a flag they should support:
> > >
> > > https://bugs.llvm.org/show_bug.cgi?id=39886
> > >
> > > Thanks for the quick reply,
> > > Nathan
> > >
> > > > > ---
> > > > >  arch/arm/Makefile | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > > > > index e2a0baf36766..4fab2aa29570 100644
> > > > > --- a/arch/arm/Makefile
> > > > > +++ b/arch/arm/Makefile
> > > > > @@ -10,7 +10,7 @@
> > > > >  #
> > > > >  # Copyright (C) 1995-2001 by Russell King
> > > > >
> > > > > -LDFLAGS_vmlinux        := --no-undefined -X --pic-veneer
> > > > > +LDFLAGS_vmlinux        := --no-undefined -X $(call ld-option,--pic-veneer)
> > > > >  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
> > > > >  LDFLAGS_vmlinux        += --be8
> > > > >  KBUILD_LDFLAGS_MODULE  += --be8
> > > > > --
> > > > > 2.20.0.rc1
> > > > >
Nick Desaulniers Dec. 5, 2018, 6:41 p.m. UTC | #8
On Wed, Dec 5, 2018 at 10:40 AM Ard Biesheuvel
<ard.biesheuvel@linaro.org> wrote:
>
> On Wed, 5 Dec 2018 at 19:36, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >
> > On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
> > > (+ Arnd)
> > >
> > > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > >
> > > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> > > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > > > >
> > > > > > This flag is not supported by lld:
> > > > > >
> > > > > >     ld.lld: error: unknown argument: --pic-veneer
> > > > > >
> > > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> > > > >
> > > > > Hi Nate,
> > > > >
> > > > > Does this mean ld.lld is guaranteed to produce position independent
> > > > > veneers if you build kernels that are bigger than the typical range of
> > > > > a relative branch?
> > > > >
> > > >
> > > > Hi Ard,
> > > >
> > > > Honestly, I'm not quite sure. I saw your commit that introduced this
> > > > flag and I wasn't quite sure what to make of it for lld. What
> > > > configuration would I use to verify and what would I check for?
> > > >
> > >
> > > Try building allyesconfig, and check the resulting binary for veneers
> > > (which have 'veneer' in the symbol name, at least when ld.bfd emits
> > > them). These veneers should not take the [virtual] address of the
> > > branch target directly, but take a PC relative offset (as in the
> > > example in the commit log of that patch you are referring to)
> > >
> >
> > Alright, compiling with allyesconfig is a little rough at the moment
> > (bug reports I will file in due time) but I was able to do it. Here's
> > the disassembly specifically for the functions you had in your commit,
> > my assembly knowledge is pretty much non-existent unfortunately so I am
> > not sure what to make of it (it doesn't look like there is a virtual
> > address for pc in that mix?). I am happy to provide any more information
> > that is needed.
> >
> > c03030cc <__enable_mmu>:
> > c03030cc:       e3c00002        bic     r0, r0, #2
> > c03030d0:       e3c00b02        bic     r0, r0, #2048   ; 0x800
> > c03030d4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
> > c03030d8:       e3a05051        mov     r5, #81 ; 0x51
> > c03030dc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
> > c03030e0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
> > c03030e4:       eafff3c5        b       c0300000 <__turn_mmu_on>
> > c03030e8:       e320f000        nop     {0}
> > c03030ec:       e320f000        nop     {0}
> > c03030f0:       e320f000        nop     {0}
> > c03030f4:       e320f000        nop     {0}
> > c03030f8:       e320f000        nop     {0}
> > c03030fc:       e320f000        nop     {0}
> >
> > c0300000 <__turn_mmu_on>:
> > c0300000:       e1a00000        nop                     ; (mov r0, r0)
> > c0300004:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> > c0300008:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
> > c030000c:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}
> > c0300010:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> > c0300014:       e1a03003        mov     r3, r3
> > c0300018:       e1a0300d        mov     r3, sp
> > c030001c:       e1a0f003        mov     pc, r3
> >
>
> Thanks Nate.
>
> So these functions no longer appear to reside far away from each
> other, so there no veneer has been emitted.
>
> What we're looking for are veneers, i.e., snippets inserted by the
> linker that serve as a trampoline so a branch target that is far away
> can be reached.
>
> If no symbols exist with 'veneer' in their name *, it might make sense
> to rebuild the kernel as Thumb2, which has a branching range of only 8
> MB (as opposed to 16 MB for ARM mode)

Heh, Arnd and I were just talking about this yesterday.  Is there a
config that sets Thumb2 mode for the kernel?

>
> * I have no idea whether lld names its veneers like this, or even at all
Peter Smith Dec. 5, 2018, 7:30 p.m. UTC | #9
On Wed, 5 Dec 2018 at 18:22, Nick Desaulniers <ndesaulniers@google.com> wrote:
>
> On Wed, Dec 5, 2018 at 12:10 AM Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
> >
> > (+ Arnd)
> >
> > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > >
> > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > > >
> > > > > This flag is not supported by lld:
> > > > >
> > > > >     ld.lld: error: unknown argument: --pic-veneer
> > > > >
> > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> > > >
> > > > Hi Nate,
> > > >
> > > > Does this mean ld.lld is guaranteed to produce position independent
> > > > veneers if you build kernels that are bigger than the typical range of
> > > > a relative branch?
>
> (+ Peter) who might be able to answer this.
>

LLD will only use position independent veneers when --shared or --pie
is used, otherwise it will use veneers with absolute addresses. If the
kernel must use position independent veneers even when the rest of the
code isn't then we'll have to implement --pic-veneer.

Peter

> > > >
> > >
> > > Hi Ard,
> > >
> > > Honestly, I'm not quite sure. I saw your commit that introduced this
> > > flag and I wasn't quite sure what to make of it for lld. What
> > > configuration would I use to verify and what would I check for?
> > >
> >
> > Try building allyesconfig, and check the resulting binary for veneers
> > (which have 'veneer' in the symbol name, at least when ld.bfd emits
> > them). These veneers should not take the [virtual] address of the
> > branch target directly, but take a PC relative offset (as in the
> > example in the commit log of that patch you are referring to)
>
> Not sure clang can compile an arm32 allyesconfig (haven't tried
> personally, yet, TODO), but we could try gcc+lld.
>
> >
> > > Additionally, I have filed an LLVM bug for the lld developers to
> > > check and see if this is a flag they should support:
> > >
> > > https://bugs.llvm.org/show_bug.cgi?id=39886
> > >
> > > Thanks for the quick reply,
> > > Nathan
> > >
> > > > > ---
> > > > >  arch/arm/Makefile | 2 +-
> > > > >  1 file changed, 1 insertion(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> > > > > index e2a0baf36766..4fab2aa29570 100644
> > > > > --- a/arch/arm/Makefile
> > > > > +++ b/arch/arm/Makefile
> > > > > @@ -10,7 +10,7 @@
> > > > >  #
> > > > >  # Copyright (C) 1995-2001 by Russell King
> > > > >
> > > > > -LDFLAGS_vmlinux        := --no-undefined -X --pic-veneer
> > > > > +LDFLAGS_vmlinux        := --no-undefined -X $(call ld-option,--pic-veneer)
> > > > >  ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
> > > > >  LDFLAGS_vmlinux        += --be8
> > > > >  KBUILD_LDFLAGS_MODULE  += --be8
> > > > > --
> > > > > 2.20.0.rc1
> > > > >
>
>
>
> --
> Thanks,
> ~Nick Desaulniers
Ard Biesheuvel Dec. 5, 2018, 9:03 p.m. UTC | #10
On Wed, 5 Dec 2018 at 20:45, Nathan Chancellor <natechancellor@gmail.com> wrote:
>
> On Wed, Dec 05, 2018 at 07:39:55PM +0100, Ard Biesheuvel wrote:
> > On Wed, 5 Dec 2018 at 19:36, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > >
> > > On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
> > > > (+ Arnd)
> > > >
> > > > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > > >
> > > > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> > > > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> > > > > > >
> > > > > > > This flag is not supported by lld:
> > > > > > >
> > > > > > >     ld.lld: error: unknown argument: --pic-veneer
> > > > > > >
> > > > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> > > > > >
> > > > > > Hi Nate,
> > > > > >
> > > > > > Does this mean ld.lld is guaranteed to produce position independent
> > > > > > veneers if you build kernels that are bigger than the typical range of
> > > > > > a relative branch?
> > > > > >
> > > > >
> > > > > Hi Ard,
> > > > >
> > > > > Honestly, I'm not quite sure. I saw your commit that introduced this
> > > > > flag and I wasn't quite sure what to make of it for lld. What
> > > > > configuration would I use to verify and what would I check for?
> > > > >
> > > >
> > > > Try building allyesconfig, and check the resulting binary for veneers
> > > > (which have 'veneer' in the symbol name, at least when ld.bfd emits
> > > > them). These veneers should not take the [virtual] address of the
> > > > branch target directly, but take a PC relative offset (as in the
> > > > example in the commit log of that patch you are referring to)
> > > >
> > >
> > > Alright, compiling with allyesconfig is a little rough at the moment
> > > (bug reports I will file in due time) but I was able to do it. Here's
> > > the disassembly specifically for the functions you had in your commit,
> > > my assembly knowledge is pretty much non-existent unfortunately so I am
> > > not sure what to make of it (it doesn't look like there is a virtual
> > > address for pc in that mix?). I am happy to provide any more information
> > > that is needed.
> > >
> > > c03030cc <__enable_mmu>:
> > > c03030cc:       e3c00002        bic     r0, r0, #2
> > > c03030d0:       e3c00b02        bic     r0, r0, #2048   ; 0x800
> > > c03030d4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
> > > c03030d8:       e3a05051        mov     r5, #81 ; 0x51
> > > c03030dc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
> > > c03030e0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
> > > c03030e4:       eafff3c5        b       c0300000 <__turn_mmu_on>
> > > c03030e8:       e320f000        nop     {0}
> > > c03030ec:       e320f000        nop     {0}
> > > c03030f0:       e320f000        nop     {0}
> > > c03030f4:       e320f000        nop     {0}
> > > c03030f8:       e320f000        nop     {0}
> > > c03030fc:       e320f000        nop     {0}
> > >
> > > c0300000 <__turn_mmu_on>:
> > > c0300000:       e1a00000        nop                     ; (mov r0, r0)
> > > c0300004:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> > > c0300008:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
> > > c030000c:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}
> > > c0300010:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> > > c0300014:       e1a03003        mov     r3, r3
> > > c0300018:       e1a0300d        mov     r3, sp
> > > c030001c:       e1a0f003        mov     pc, r3
> > >
> >
> > Thanks Nate.
> >
> > So these functions no longer appear to reside far away from each
> > other, so there no veneer has been emitted.
> >
> > What we're looking for are veneers, i.e., snippets inserted by the
> > linker that serve as a trampoline so a branch target that is far away
> > can be reached.
> >
> > If no symbols exist with 'veneer' in their name *, it might make sense
> > to rebuild the kernel as Thumb2, which has a branching range of only 8
> > MB (as opposed to 16 MB for ARM mode)
> >
> > * I have no idea whether lld names its veneers like this, or even at all
>
> Thanks Ard, I understand now, I appreciate that.
>
> I compiled with CONFIG_THUMB2_KERNEL (config attached) and I am still
> not seeing any veneers or thunks as Peter said they would be called for
> lld in the LLVM bug report linked earlier in the thread. Peter did note
> that the branch ranges were 32MB and 16MB for ARM and Thumb2
> respectively, which could be playing into this.
>

Ah, indeed. Off by one :-)

However, even when building in ARM rather than Thumb2 mode,
allyesconfig gives me

ard@harold:~/linux-build-arm$ size vmlinux
   text    data     bss     dec     hex filename
107708906 50335363 15258568 173302837 a546435 vmlinux
ard@harold:~/linux-build-arm$ grep -cE _veneer$ System.map
16199

so surely, lld is emitting veneers but perhaps it doesn't emit symbols
for them in the same way as ld.bfd does.

Actually, most of those veneers are fine, given that the vast majority
of the code will only run at its proper link time address. However,
some pieces run with the MMU off, either at early boot or around
suspend/resume, and so we need veneers to be position independent.
Stefan Agner Dec. 5, 2018, 10:59 p.m. UTC | #11
On 05.12.2018 19:41, Nick Desaulniers wrote:
> On Wed, Dec 5, 2018 at 10:40 AM Ard Biesheuvel
> <ard.biesheuvel@linaro.org> wrote:
>>
>> On Wed, 5 Dec 2018 at 19:36, Nathan Chancellor <natechancellor@gmail.com> wrote:
>> >
>> > On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
>> > > (+ Arnd)
>> > >
>> > > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
>> > > >
>> > > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
>> > > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
>> > > > > >
>> > > > > > This flag is not supported by lld:
>> > > > > >
>> > > > > >     ld.lld: error: unknown argument: --pic-veneer
>> > > > > >
>> > > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
>> > > > >
>> > > > > Hi Nate,
>> > > > >
>> > > > > Does this mean ld.lld is guaranteed to produce position independent
>> > > > > veneers if you build kernels that are bigger than the typical range of
>> > > > > a relative branch?
>> > > > >
>> > > >
>> > > > Hi Ard,
>> > > >
>> > > > Honestly, I'm not quite sure. I saw your commit that introduced this
>> > > > flag and I wasn't quite sure what to make of it for lld. What
>> > > > configuration would I use to verify and what would I check for?
>> > > >
>> > >
>> > > Try building allyesconfig, and check the resulting binary for veneers
>> > > (which have 'veneer' in the symbol name, at least when ld.bfd emits
>> > > them). These veneers should not take the [virtual] address of the
>> > > branch target directly, but take a PC relative offset (as in the
>> > > example in the commit log of that patch you are referring to)
>> > >
>> >
>> > Alright, compiling with allyesconfig is a little rough at the moment
>> > (bug reports I will file in due time) but I was able to do it. Here's
>> > the disassembly specifically for the functions you had in your commit,
>> > my assembly knowledge is pretty much non-existent unfortunately so I am
>> > not sure what to make of it (it doesn't look like there is a virtual
>> > address for pc in that mix?). I am happy to provide any more information
>> > that is needed.
>> >
>> > c03030cc <__enable_mmu>:
>> > c03030cc:       e3c00002        bic     r0, r0, #2
>> > c03030d0:       e3c00b02        bic     r0, r0, #2048   ; 0x800
>> > c03030d4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
>> > c03030d8:       e3a05051        mov     r5, #81 ; 0x51
>> > c03030dc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
>> > c03030e0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
>> > c03030e4:       eafff3c5        b       c0300000 <__turn_mmu_on>
>> > c03030e8:       e320f000        nop     {0}
>> > c03030ec:       e320f000        nop     {0}
>> > c03030f0:       e320f000        nop     {0}
>> > c03030f4:       e320f000        nop     {0}
>> > c03030f8:       e320f000        nop     {0}
>> > c03030fc:       e320f000        nop     {0}
>> >
>> > c0300000 <__turn_mmu_on>:
>> > c0300000:       e1a00000        nop                     ; (mov r0, r0)
>> > c0300004:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
>> > c0300008:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
>> > c030000c:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}
>> > c0300010:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
>> > c0300014:       e1a03003        mov     r3, r3
>> > c0300018:       e1a0300d        mov     r3, sp
>> > c030001c:       e1a0f003        mov     pc, r3
>> >
>>
>> Thanks Nate.
>>
>> So these functions no longer appear to reside far away from each
>> other, so there no veneer has been emitted.
>>
>> What we're looking for are veneers, i.e., snippets inserted by the
>> linker that serve as a trampoline so a branch target that is far away
>> can be reached.
>>
>> If no symbols exist with 'veneer' in their name *, it might make sense
>> to rebuild the kernel as Thumb2, which has a branching range of only 8
>> MB (as opposed to 16 MB for ARM mode)
> 
> Heh, Arnd and I were just talking about this yesterday.  Is there a
> config that sets Thumb2 mode for the kernel?
> 

Yes there is CONFIG_THUMB2_KERNEL, and it works also with LLVM/Clang.

However, it sometimes leads to surprising issues, like I just
encountered a few days ago:

https://lore.kernel.org/linux-pci/20181126161645.8177-1-stefan@agner.ch/

--
Stefan

>>
>> * I have no idea whether lld names its veneers like this, or even at all
Nick Desaulniers Dec. 5, 2018, 11:19 p.m. UTC | #12
On Wed, Dec 5, 2018 at 2:59 PM Stefan Agner <stefan@agner.ch> wrote:
>
> On 05.12.2018 19:41, Nick Desaulniers wrote:
> > On Wed, Dec 5, 2018 at 10:40 AM Ard Biesheuvel
> > <ard.biesheuvel@linaro.org> wrote:
> >>
> >> On Wed, 5 Dec 2018 at 19:36, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >> >
> >> > On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
> >> > > (+ Arnd)
> >> > >
> >> > > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >> > > >
> >> > > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> >> > > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >> > > > > >
> >> > > > > > This flag is not supported by lld:
> >> > > > > >
> >> > > > > >     ld.lld: error: unknown argument: --pic-veneer
> >> > > > > >
> >> > > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> >> > > > >
> >> > > > > Hi Nate,
> >> > > > >
> >> > > > > Does this mean ld.lld is guaranteed to produce position independent
> >> > > > > veneers if you build kernels that are bigger than the typical range of
> >> > > > > a relative branch?
> >> > > > >
> >> > > >
> >> > > > Hi Ard,
> >> > > >
> >> > > > Honestly, I'm not quite sure. I saw your commit that introduced this
> >> > > > flag and I wasn't quite sure what to make of it for lld. What
> >> > > > configuration would I use to verify and what would I check for?
> >> > > >
> >> > >
> >> > > Try building allyesconfig, and check the resulting binary for veneers
> >> > > (which have 'veneer' in the symbol name, at least when ld.bfd emits
> >> > > them). These veneers should not take the [virtual] address of the
> >> > > branch target directly, but take a PC relative offset (as in the
> >> > > example in the commit log of that patch you are referring to)
> >> > >
> >> >
> >> > Alright, compiling with allyesconfig is a little rough at the moment
> >> > (bug reports I will file in due time) but I was able to do it. Here's
> >> > the disassembly specifically for the functions you had in your commit,
> >> > my assembly knowledge is pretty much non-existent unfortunately so I am
> >> > not sure what to make of it (it doesn't look like there is a virtual
> >> > address for pc in that mix?). I am happy to provide any more information
> >> > that is needed.
> >> >
> >> > c03030cc <__enable_mmu>:
> >> > c03030cc:       e3c00002        bic     r0, r0, #2
> >> > c03030d0:       e3c00b02        bic     r0, r0, #2048   ; 0x800
> >> > c03030d4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
> >> > c03030d8:       e3a05051        mov     r5, #81 ; 0x51
> >> > c03030dc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
> >> > c03030e0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
> >> > c03030e4:       eafff3c5        b       c0300000 <__turn_mmu_on>
> >> > c03030e8:       e320f000        nop     {0}
> >> > c03030ec:       e320f000        nop     {0}
> >> > c03030f0:       e320f000        nop     {0}
> >> > c03030f4:       e320f000        nop     {0}
> >> > c03030f8:       e320f000        nop     {0}
> >> > c03030fc:       e320f000        nop     {0}
> >> >
> >> > c0300000 <__turn_mmu_on>:
> >> > c0300000:       e1a00000        nop                     ; (mov r0, r0)
> >> > c0300004:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> >> > c0300008:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
> >> > c030000c:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}
> >> > c0300010:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
> >> > c0300014:       e1a03003        mov     r3, r3
> >> > c0300018:       e1a0300d        mov     r3, sp
> >> > c030001c:       e1a0f003        mov     pc, r3
> >> >
> >>
> >> Thanks Nate.
> >>
> >> So these functions no longer appear to reside far away from each
> >> other, so there no veneer has been emitted.
> >>
> >> What we're looking for are veneers, i.e., snippets inserted by the
> >> linker that serve as a trampoline so a branch target that is far away
> >> can be reached.
> >>
> >> If no symbols exist with 'veneer' in their name *, it might make sense
> >> to rebuild the kernel as Thumb2, which has a branching range of only 8
> >> MB (as opposed to 16 MB for ARM mode)
> >
> > Heh, Arnd and I were just talking about this yesterday.  Is there a
> > config that sets Thumb2 mode for the kernel?
> >
>
> Yes there is CONFIG_THUMB2_KERNEL, and it works also with LLVM/Clang.

Sounds like something we should put under CI?
https://github.com/ClangBuiltLinux/continuous-integration/issues/94

>
> However, it sometimes leads to surprising issues, like I just
> encountered a few days ago:
>
> https://lore.kernel.org/linux-pci/20181126161645.8177-1-stefan@agner.ch/
>
> --
> Stefan
>
> >>
> >> * I have no idea whether lld names its veneers like this, or even at all
Stefan Agner Dec. 29, 2018, 12:27 p.m. UTC | #13
On 05.12.2018 20:45, Nathan Chancellor wrote:
> On Wed, Dec 05, 2018 at 07:39:55PM +0100, Ard Biesheuvel wrote:
>> On Wed, 5 Dec 2018 at 19:36, Nathan Chancellor <natechancellor@gmail.com> wrote:
>> >
>> > On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
>> > > (+ Arnd)
>> > >
>> > > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
>> > > >
>> > > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
>> > > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
>> > > > > >
>> > > > > > This flag is not supported by lld:
>> > > > > >
>> > > > > >     ld.lld: error: unknown argument: --pic-veneer
>> > > > > >
>> > > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
>> > > > >
>> > > > > Hi Nate,
>> > > > >
>> > > > > Does this mean ld.lld is guaranteed to produce position independent
>> > > > > veneers if you build kernels that are bigger than the typical range of
>> > > > > a relative branch?
>> > > > >
>> > > >
>> > > > Hi Ard,
>> > > >
>> > > > Honestly, I'm not quite sure. I saw your commit that introduced this
>> > > > flag and I wasn't quite sure what to make of it for lld. What
>> > > > configuration would I use to verify and what would I check for?
>> > > >
>> > >
>> > > Try building allyesconfig, and check the resulting binary for veneers
>> > > (which have 'veneer' in the symbol name, at least when ld.bfd emits
>> > > them). These veneers should not take the [virtual] address of the
>> > > branch target directly, but take a PC relative offset (as in the
>> > > example in the commit log of that patch you are referring to)
>> > >
>> >
>> > Alright, compiling with allyesconfig is a little rough at the moment
>> > (bug reports I will file in due time) but I was able to do it. Here's
>> > the disassembly specifically for the functions you had in your commit,
>> > my assembly knowledge is pretty much non-existent unfortunately so I am
>> > not sure what to make of it (it doesn't look like there is a virtual
>> > address for pc in that mix?). I am happy to provide any more information
>> > that is needed.
>> >
>> > c03030cc <__enable_mmu>:
>> > c03030cc:       e3c00002        bic     r0, r0, #2
>> > c03030d0:       e3c00b02        bic     r0, r0, #2048   ; 0x800
>> > c03030d4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
>> > c03030d8:       e3a05051        mov     r5, #81 ; 0x51
>> > c03030dc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
>> > c03030e0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
>> > c03030e4:       eafff3c5        b       c0300000 <__turn_mmu_on>
>> > c03030e8:       e320f000        nop     {0}
>> > c03030ec:       e320f000        nop     {0}
>> > c03030f0:       e320f000        nop     {0}
>> > c03030f4:       e320f000        nop     {0}
>> > c03030f8:       e320f000        nop     {0}
>> > c03030fc:       e320f000        nop     {0}
>> >
>> > c0300000 <__turn_mmu_on>:
>> > c0300000:       e1a00000        nop                     ; (mov r0, r0)
>> > c0300004:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
>> > c0300008:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
>> > c030000c:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}
>> > c0300010:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
>> > c0300014:       e1a03003        mov     r3, r3
>> > c0300018:       e1a0300d        mov     r3, sp
>> > c030001c:       e1a0f003        mov     pc, r3
>> >
>>
>> Thanks Nate.
>>
>> So these functions no longer appear to reside far away from each
>> other, so there no veneer has been emitted.
>>
>> What we're looking for are veneers, i.e., snippets inserted by the
>> linker that serve as a trampoline so a branch target that is far away
>> can be reached.
>>
>> If no symbols exist with 'veneer' in their name *, it might make sense
>> to rebuild the kernel as Thumb2, which has a branching range of only 8
>> MB (as opposed to 16 MB for ARM mode)
>>
>> * I have no idea whether lld names its veneers like this, or even at all
> 
> Thanks Ard, I understand now, I appreciate that.
> 
> I compiled with CONFIG_THUMB2_KERNEL (config attached) and I am still
> not seeing any veneers or thunks as Peter said they would be called for
> lld in the LLVM bug report linked earlier in the thread. Peter did note
> that the branch ranges were 32MB and 16MB for ARM and Thumb2
> respectively, which could be playing into this.
> 
> c03028d0 <__enable_mmu>:
> c03028d0:       f020 0002       bic.w   r0, r0, #2
> c03028d4:       f420 6000       bic.w   r0, r0, #2048   ; 0x800
> c03028d8:       f420 5080       bic.w   r0, r0, #4096   ; 0x1000
> c03028dc:       f04f 0551       mov.w   r5, #81 ; 0x51
> c03028e0:       ee03 5f10       mcr     15, 0, r5, cr3, cr0, {0}
> c03028e4:       ee02 4f10       mcr     15, 0, r4, cr2, cr0, {0}
> c03028e8:       f7fd bb8a       b.w     c0300000 <__turn_mmu_on>
> c03028ec:       f3af 8000       nop.w
> c03028f0:       f3af 8000       nop.w
> c03028f4:       f3af 8000       nop.w
> c03028f8:       f3af 8000       nop.w
> c03028fc:       f3af 8000       nop.w
> 
> c0300000 <__turn_mmu_on>:
> c0300000:       4600            mov     r0, r0
> c0300002:       f3bf 8f6f       isb     sy
> c0300006:       ee01 0f10       mcr     15, 0, r0, cr1, cr0, {0}
> c030000a:       ee10 3f10       mrc     15, 0, r3, cr0, cr0, {0}
> c030000e:       f3bf 8f6f       isb     sy
> c0300012:       461b            mov     r3, r3
> c0300014:       466b            mov     r3, sp
> c0300016:       469f            mov     pc, r3
> 
> Thanks for all the insight you've given!
> Nathan

I was able to reproduce the issue by using allyesconfig, removing
--pic-veneer and reverting eb765c1ceb27 ("ARM: 8317/1: move the
.idmap.text section closer to .head.text"). I guess due to that fix the
issue currently does not appear in practice (or at least not in that
particular case we are looking at).

Using ld.bfd:
$ arm-buildroot-linux-gnueabihf-objdump -d vmlinux | grep -C 4
turn_mmu_on
c020815c:       e12fff1e        bx      lr
c0208160:       cc3c2857        .word   0xcc3c2857
c0208164:       fd883000        .word   0xfd883000

c0208168 <__turn_mmu_on_loc>:
c0208168:       c0208168        .word   0xc0208168
c020816c:       c7b11230        .word   0xc7b11230
c0208170:       c7b11250        .word   0xc7b11250

--
c0303304:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
c0303308:       e3a05051        mov     r5, #81 ; 0x51
c030330c:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
c0303310:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
c0303314:       ea0fd9c7        b       c06f9a38
<____turn_mmu_on_veneer>
c0303318:       e320f000        nop     {0}
c030331c:       e320f000        nop     {0}

c0303320 <__do_fixup_smp_on_up>:
--
c06f9a30 <__bus_register_notifier_veneer>:
c06f9a30:       e51ff004        ldr     pc, [pc, #-4]   ; c06f9a34
<__bus_register_notifier_veneer+0x4>
c06f9a34:       c29752c0        .word   0xc29752c0

c06f9a38 <____turn_mmu_on_veneer>:
c06f9a38:       e51ff004        ldr     pc, [pc, #-4]   ; c06f9a3c
<____turn_mmu_on_veneer+0x4>
c06f9a3c:       c7b11230        .word   0xc7b11230

c06f9a40 <__rb_replace_node_veneer>:
c06f9a40:       e51ff004        ldr     pc, [pc, #-4]   ; c06f9a44
<__rb_replace_node_veneer+0x4>
 --

c7b1122c <__kprobes_text_end>:
c7b1122c:       00000000        .word   0x00000000

c7b11230 <__turn_mmu_on>:
c7b11230:       e1a00000        nop                     ; (mov r0, r0)
c7b11234:       ee070f95        mcr     15, 0, r0, cr7, cr5, {4}
c7b11238:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
c7b1123c:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}


And with ld.lld:

$ arm-buildroot-linux-gnueabihf-objdump -d vmlinux | grep -C 4
turn_mmu_on
c0208158:       e12fff1e        bx      lr
c020815c:       cb2cb747        .word   0xcb2cb747
c0208160:       fd883000        .word   0xfd883000

c0208164 <__turn_mmu_on_loc>:
c0208164:       c0208164        .word   0xc0208164
c0208168:       c6c3ca38        .word   0xc6c3ca38
c020816c:       c6c3ca58        .word   0xc6c3ca58

--
c0301fb4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
c0301fb8:       e3a05051        mov     r5, #81 ; 0x51
c0301fbc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
c0301fc0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
c0301fc4:       ea3f3e38        b       c12d18ac
<__ARMv7ABSLongThunk___turn_mmu_on>
c0301fc8:       e320f000        nop     {0}
c0301fcc:       e320f000        nop     {0}
c0301fd0:       e320f000        nop     {0}
c0301fd4:       e320f000        nop     {0}
--
c12d18a0:       e3a00001        mov     r0, #1
c12d18a4:       e28dd004        add     sp, sp, #4
c12d18a8:       e8bd8ff0        pop     {r4, r5, r6, r7, r8, r9, sl, fp,
pc}

c12d18ac <__ARMv7ABSLongThunk___turn_mmu_on>:
c12d18ac:       e30cca38        movw    ip, #51768      ; 0xca38
c12d18b0:       e34cc6c3        movt    ip, #50883      ; 0xc6c3
c12d18b4:       e12fff1c        bx      ip

--
c6c3ca2c:       e309c90c        movw    ip, #39180      ; 0x990c
c6c3ca30:       e34cc032        movt    ip, #49202      ; 0xc032
c6c3ca34:       e12fff1c        bx      ip

c6c3ca38 <__turn_mmu_on>:
c6c3ca38:       e1a00000        nop                     ; (mov r0, r0)
c6c3ca3c:       f57ff06f        isb     sy
c6c3ca40:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
c6c3ca44:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}

With --pic-veneer and ld.bfd:

 $ arm-buildroot-linux-gnueabihf-objdump -d vmlinux | grep -C 4
turn_mmu_on
c0208158:       e12fff1e        bx      lr
c020815c:       cb1cb747        .word   0xcb1cb747
c0208160:       fd883000        .word   0xfd883000

c0208164 <__turn_mmu_on_loc>:
c0208164:       c0208164        .word   0xc0208164
c0208168:       c6c514e0        .word   0xc6c514e0
c020816c:       c6c51500        .word   0xc6c51500

--
c0301fb4:       e3c00a01        bic     r0, r0, #4096   ; 0x1000
c0301fb8:       e3a05051        mov     r5, #81 ; 0x51
c0301fbc:       ee035f10        mcr     15, 0, r5, cr3, cr0, {0}
c0301fc0:       ee024f10        mcr     15, 0, r4, cr2, cr0, {0}
c0301fc4:       ea0fd5a4        b       c06f765c
<____turn_mmu_on_veneer>
c0301fc8:       e320f000        nop     {0}
c0301fcc:       e320f000        nop     {0}
c0301fd0:       e320f000        nop     {0}
c0301fd4:       e320f000        nop     {0}
--
c06f7650:       e59fc000        ldr     ip, [pc]        ; c06f7658
<____xa_set_mark_veneer+0x8>
c06f7654:       e08ff00c        add     pc, pc, ip
c06f7658:       0654cebc        .word   0x0654cebc

c06f765c <____turn_mmu_on_veneer>:
c06f765c:       e59fc000        ldr     ip, [pc]        ; c06f7664
<____turn_mmu_on_veneer+0x8>
c06f7660:       e08ff00c        add     pc, pc, ip
c06f7664:       06559e78        .word   0x06559e78

--
c6c514d4:       e1a00006        mov     r0, r6
c6c514d8:       e8bd4070        pop     {r4, r5, r6, lr}
c6c514dc:       e12fff13        bx      r3

c6c514e0 <__turn_mmu_on>:
c6c514e0:       e1a00000        nop                     ; (mov r0, r0)
c6c514e4:       f57ff06f        isb     sy
c6c514e8:       ee010f10        mcr     15, 0, r0, cr1, cr0, {0}
c6c514ec:       ee103f10        mrc     15, 0, r3, cr0, cr0, {0}

--
Stefan
Nick Desaulniers Jan. 7, 2019, 7:42 p.m. UTC | #14
On Sat, Dec 29, 2018 at 4:27 AM Stefan Agner <stefan@agner.ch> wrote:
>
> On 05.12.2018 20:45, Nathan Chancellor wrote:
> > On Wed, Dec 05, 2018 at 07:39:55PM +0100, Ard Biesheuvel wrote:
> >> On Wed, 5 Dec 2018 at 19:36, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >> >
> >> > On Wed, Dec 05, 2018 at 09:09:56AM +0100, Ard Biesheuvel wrote:
> >> > > (+ Arnd)
> >> > >
> >> > > On Wed, 5 Dec 2018 at 09:06, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >> > > >
> >> > > > On Wed, Dec 05, 2018 at 08:37:05AM +0100, Ard Biesheuvel wrote:
> >> > > > > On Wed, 5 Dec 2018 at 02:42, Nathan Chancellor <natechancellor@gmail.com> wrote:
> >> > > > > >
> >> > > > > > This flag is not supported by lld:
> >> > > > > >
> >> > > > > >     ld.lld: error: unknown argument: --pic-veneer
> >> > > > > >
> >> > > > > > Signed-off-by: Nathan Chancellor <natechancellor@gmail.com>
> >> > > > >
> >> > > > > Hi Nate,
> >> > > > >
> >> > > > > Does this mean ld.lld is guaranteed to produce position independent
> >> > > > > veneers if you build kernels that are bigger than the typical range of
> >> > > > > a relative branch?

Just for the list, 2 patches to lld:
https://github.com/ClangBuiltLinux/linux/issues/286#issuecomment-452027802
diff mbox series

Patch

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index e2a0baf36766..4fab2aa29570 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -10,7 +10,7 @@ 
 #
 # Copyright (C) 1995-2001 by Russell King
 
-LDFLAGS_vmlinux	:= --no-undefined -X --pic-veneer
+LDFLAGS_vmlinux	:= --no-undefined -X $(call ld-option,--pic-veneer)
 ifeq ($(CONFIG_CPU_ENDIAN_BE8),y)
 LDFLAGS_vmlinux	+= --be8
 KBUILD_LDFLAGS_MODULE	+= --be8