Page MenuHomePhabricator

clang: Always pass PowerPC endian information to GNU as
ClosedPublic

Authored by nathanchance on Mon, Jan 11, 12:15 PM.

Details

Summary

When building a 64-bit big endian PowerPC Linux kernel with a 64-bit
little endian PowerPC target, the 32-bit vDSO errors:

$ make ARCH=powerpc CC=clang CROSS_COMPILE=powerpc64le-linux-gnu- \
       pseries_defconfig arch/powerpc/kernel/vdso32/
ld.lld: error: arch/powerpc/kernel/vdso32/sigtramp.o is incompatible with elf32-powerpc
ld.lld: error: arch/powerpc/kernel/vdso32/gettimeofday.o is incompatible with elf32-powerpc
ld.lld: error: arch/powerpc/kernel/vdso32/datapage.o is incompatible with elf32-powerpc
ld.lld: error: arch/powerpc/kernel/vdso32/cacheflush.o is incompatible with elf32-powerpc
ld.lld: error: arch/powerpc/kernel/vdso32/note.o is incompatible with elf32-powerpc
ld.lld: error: arch/powerpc/kernel/vdso32/getcpu.o is incompatible with elf32-powerpc
ld.lld: error: arch/powerpc/kernel/vdso32/vgettimeofday.o is incompatible with elf32-powerpc
...

This happens because the endian information is missing from the call to
the assembler, even though it was explicitly passed to clang. See the
below example.

$ echo | clang --target=powerpc64le-linux-gnu \
               --prefix=/usr/bin/powerpc64le-linux-gnu- \
               -no-integrated-as -m32 -mbig-endian -### -x c -c -
 ".../clang-12" "-cc1" "-triple" "powerpc-unknown-linux-gnu" ...
...
  "/usr/bin/powerpc64le-linux-gnu-as" "-a32" "-mppc" "-many" "-o" "-.o" "/tmp/--e69e28.s"

clang sets the right target with -m32 and -mbig-endian but -mbig-endian
does not make it to the assembler, resulting in a 32-bit little endian
binary. This differs from the little endian targets, which always pass
-mlittle-endian.

$ echo | clang --target=powerpc64-linux-gnu \
               --prefix=/usr/bin/powerpc64-linux-gnu- \
               -no-integrated-as -m32 -mlittle-endian -### -x c -c -
 ".../clang-12" "-cc1" "-triple" "powerpcle-unknown-linux-gnu" ...
...
 "/usr/bin/powerpc64-linux-gnu-as" "-a32" "-mppc" "-mlittle-endian" "-many" "-o" "-.o" "/tmp/--405dbd.s"

Do the same thing for the big endian targets so that there is no more
error. This matches GCC's behavior, where -mbig and -mlittle are always
passed along to GNU as.

$ echo | powerpc64-linux-gcc -### -x c -c -
...
.../powerpc64-linux/bin/as -a64 -mpower4 -many -mbig -o -.o /tmp/ccVn7NAm.s
...

$ echo | powerpc64le-linux-gcc -### -x c -c -
...
.../powerpc64le-linux/bin/as -a64 -mpower8 -many -mlittle -o -.o /tmp/ccPN9ato.s
...

Diff Detail

Event Timeline

nathanchance created this revision.Mon, Jan 11, 12:15 PM
nathanchance requested review of this revision.Mon, Jan 11, 12:15 PM

This differs from the little endian targets, which always pass
-mbig-endian.

I think you meant -mlittle-endian here?

nathanchance edited the summary of this revision. (Show Details)Mon, Jan 11, 12:27 PM

Indeed, updated!

MaskRay accepted this revision.Mon, Jan 11, 1:49 PM
MaskRay added a subscriber: MaskRay.

LGTM.

Context not available.

https://llvm.org/docs/GettingStarted.html#sending-patches arc diff HEAD~1 is convenient as it automatically sends the context lines.

clang/test/Driver/ppc-features.cpp
161

CHECK_32_BE_AS_ARGS-SAME: is slightly better (checking the the content is on the same line).

This revision is now accepted and ready to land.Mon, Jan 11, 1:49 PM

Addressed Fangrui's comments. If this looks good, please commit it on my behalf: Nathan Chancellor <natechancellor@gmail.com>

nathanchance marked an inline comment as done.Mon, Jan 11, 2:14 PM
nathanchance added inline comments.
clang/test/Driver/ppc-features.cpp
161

Thanks, I will remember that for the future :)

nickdesaulniers accepted this revision.Mon, Jan 11, 2:38 PM

Sure. I'll commit it.

Herald added a project: Restricted Project. · View Herald TranscriptMon, Jan 11, 2:51 PM
Herald added a subscriber: cfe-commits. · View Herald Transcript