Re: [PATCH] powerpc: allow cross-compilation of ppc64 kernel
From: Laurent Vivier
Date: Fri Nov 06 2015 - 17:22:40 EST
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)
But in the case of vdso64, ld command is gcc:
arch/powerpc/kernel/vdso64/Makefile:
cmd_vdso64ld = $(CC) $(c_flags) -Wl,-T $^ -o $@
So to link, we use "gcc -mlittle-endian -m64"
and strace of "gcc -mlittle-endian -m64" gives me:
"/usr/libexec/gcc/ppc64-redhat-linux/5.1.1/collect2", [ ... "--oformat",
"elf32-powerpcle", "-m", "elf64lppc",...
So the format used to link is by default "elf32-powerpcle" (with the
emulation elf64lppc given by "-mlittle-endian -m64", I agree it seems
strange).
I think this is coming from the configuration of my gcc, "-dumpspecs"
gives me:
*link_target:
%{mlittle|mlittle-endian: --oformat
elf32-powerpcle;mbig|mbig-endian:;mcall-i960-old: --oformat
elf32-powerpcle;:}
When "ld" is called without "--oformat" it takes the format of the first
processed object ("elf64-powerpcle" in our case, it's why it works for
the other binaries of the kernel).
So at this point, I can:
1- either fix my compiler,
2- or fix the vdso64 linker command.
As all the others objects of the kernel are generated and linked
correctly with this build env, there is no reason to not choose 2- as 1-
is much more complex (at leasts for me = rebuild gcc whereas I just want
to build the kernel).
But, more generally, what I'm wondering is why we are using CC instead
of LD to link objects...
Laurent
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/