Subject: Re: [PATCH] powerpc: allow cross-compilation of ppc64 kernel

From: Laurent Vivier <[email-masked]>
Date: Sat, 7 Nov 2015 12:35:31 +0100

Le 07/11/2015 00:24, Scott Wood a écrit :
> On Fri, 2015-11-06 at 23:22 +0100, Laurent Vivier wrote:
>> Le 06/11/2015 22:09, Scott Wood a écrit :
>>> On Thu, 2015-11-05 at 12:47 +0100, Laurent Vivier wrote:
>>>> When I try to cross compile a ppc64 kernel, it generally
>>>> fails on the VDSO stage. This is true for powerpc64 cross-
>>>> compiler, but also when I try to build a ppc64le kernel
>>>> on a ppc64 host.
>>>>
>>>> VDSO64L fails:
>>>>
>>>>   VDSO64L arch/powerpc/kernel/vdso64/vdso64.so.dbg
>>>> /usr/bin/powerpc64-linux-gnu-ld: arch/powerpc/kernel/vdso64/sigtramp.o:
>>>> file class ELFCLASS64 incompatible with ELFCLASS32
>>>> /usr/bin/powerpc64-linux-gnu-ld: final link failed: File in wrong format
>>>>
>>>> This fails because gcc calls "collect2" with
>>>> "--oformat elf32-powerpcle" with ppc64 objects, without the
>>>> "--oformat" ld works well because it use the format of the
>>>> first object as output format.
>>>>
>>>> As this case is correctly managed to build the other kernel
>>>> objects, this patch replaces $(GCC) by $(LD) to generate the
>>>> VDSO objects.
>>>
>>> I cross-compile ppc64 kernels and have not seen this problem.  I do need 
>>> to 
>>> pass in -m64 as part of $(CC) if it's not the toolchain default, which is 
>>> not 
>>> nice, but the proper fix for that is to add -m64 in the makefiles -- and 
>>> if I 
>>> don't it fails way before VDSO.
>>>
>>> Why is GCC building ppc64 object files but telling the linker --oformat 
>>> elf32-
>>> powerpcle?  Are different options somehow being passed to GCC in one case 
>>> versus the other?
>>
>> In fact, for all the other parts of the kernel, gcc is called with
>> "-mlittle-endian -m64", ld with "-EL -m elf64lppc", and thus generates
>> the good objects and calls ld with the good options ("elf64lppc"). I
>> think gcc is never used to link, only to compile.
>> This, I think, comes from:
>>
>> arch/powerpc/Makefile:
>>
>> ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y)
>> override CC     += -mlittle-endian
>> override LD     += -EL
>> ...
>> ifeq ($(HAS_BIARCH),y)
>> override CC     += -m$(CONFIG_WORD_SIZE)
>> override LD     += -m elf$(CONFIG_WORD_SIZE)$(LDEMULATION)
> 
> OK, that works if I completely remove the CC environment setting rather than 
> just remove the -m64 from it.  It looks like that's been there longer than 
> I've been building 64-bit kernels, so I wonder what originally prompted me to 
> add the environment setting.
> 
> Yes, the kernel itself is linked with ld rather than gcc, but that's unusual. 
>  There's nothing wrong with using gcc to link.
> 
>> So at this point, I can:
>>
>> 1- either fix my compiler,
>> 2- or fix the vdso64 linker command.
> 
> Do #1, as that's where the bug is, and if you work around it you'll have the 
> same problem building other projects if they happen to specify the endianness 
> explicitly.

Thank you Scott. With the help of the comment from Segher, I can choose
#1 now :)

Laurent