ClangBuiltLinux / linux

Linux kernel source tree
Other
242 stars 14 forks source link

invalid operand in line asm '.ascii ".... $0 ..."' when cross compiled with m68k #1242

Closed mshockwave closed 3 years ago

mshockwave commented 3 years ago

When cross compile with m68k:

ARCH=m68k CROSS_COMPILE=m68k-linux-gnu- make CC="/path/to/clang" -j defconf
ARCH=m68k CROSS_COMPILE=m68k-linux-gnu- make CC="/path/to/clang" -j

A tons of error messages similar to the one below were thrown from scripts/mod/devicetable-offsets.c:

scripts/mod/devicetable-offsets.c:31:2: error: invalid operand in inline asm: '.ascii "->SIZE_ieee1394_device_id $0 sizeof(struct ieee1394_device_id)"'
        DEVID(ieee1394_device_id);
        ^
scripts/mod/devicetable-offsets.c:5:22: note: expanded from macro 'DEVID'
#define DEVID(devid) DEFINE(SIZE_##devid, sizeof(struct devid))
                     ^
./include/linux/kbuild.h:6:15: note: expanded from macro 'DEFINE'
        asm volatile("\n.ascii \"->" #sym " %0 " #val "\"" : : "i" (val))

This might be caused by the fact that the current M68k LLVM assembler can't handle the $0 placeholder or even the ascii directive properly.

nickdesaulniers commented 3 years ago

cc @jcai19 who was just looking into the .ascii directive.

nickdesaulniers commented 3 years ago

@mshockwave can you test https://reviews.llvm.org/D91460 or ensure you tested with that commit?

nickdesaulniers commented 3 years ago

Also, @mshockwave can you preprocess the file for a reduced test case? make CC=clang <path/to/file.i> should work.

glaubitz commented 3 years ago

This is still reproducible:

  CC      scripts/mod/devicetable-offsets.s
scripts/mod/devicetable-offsets.c:11:2: error: invalid operand in inline asm: '.ascii "->SIZE_usb_device_id $0 sizeof(struct usb_device_id)"'
        DEVID(usb_device_id);
        ^
scripts/mod/devicetable-offsets.c:5:22: note: expanded from macro 'DEVID'
#define DEVID(devid) DEFINE(SIZE_##devid, sizeof(struct devid))
                     ^
./include/linux/kbuild.h:6:15: note: expanded from macro 'DEFINE'
        asm volatile("\n.ascii \"->" #sym " %0 " #val "\"" : : "i" (val))
                     ^
scripts/mod/devicetable-offsets.c:12:2: error: invalid operand in inline asm: '.ascii "->OFF_usb_device_id_match_flags $0 offsetof(struct usb_device_id, match_flags)"'
        DEVID_FIELD(usb_device_id, match_flags);
        ^
scripts/mod/devicetable-offsets.c:7:2: note: expanded from macro 'DEVID_FIELD'
        DEFINE(OFF_##devid##_##field, offsetof(struct devid, field))

Strangely, I cannot create the pre-processed source in this case:

glaubitz@node54:/data/home/glaubitz/linux> ARCH=m68k CROSS_COMPILE=m68k-suse-linux- make CC=clang scripts/mod/devicetable-offsets.i
glaubitz@node54:/data/home/glaubitz/linux> find . -name devicetable-offsets.i
glaubitz@node54:/data/home/glaubitz/linux>
glaubitz commented 3 years ago

devicetable-offsets.i.txt

nickdesaulniers commented 3 years ago
$ clang --target=m68k-linux-gnu foo.c
struct usb_device_id { int foo; };
void bar(void) {
        asm volatile("\n.ascii \"->" "SIZE_usb_device_id" " %0 " "sizeof(struct usb_device_id)" "\"" : : "i" (sizeof(struct usb_device_id)));
}
nickdesaulniers commented 3 years ago
struct usb_device_id { int foo; };
void bar(void) {
        asm volatile("\n.ascii \"foo\"" : : "i" (sizeof(struct usb_device_id)));
}

works, so it must be the %0. Yeah:

struct usb_device_id { int foo; };
void bar(void) {
        asm volatile("; %0" : : "i" (sizeof(struct usb_device_id)));
}
mshockwave commented 3 years ago

Patch for this issue is on Phab now: https://reviews.llvm.org/D102585 Feel free to make yourself a reviewer :-)

nathanchance commented 3 years ago

https://github.com/llvm/llvm-project/commit/dccf5c7dfb9e68f8750947f5c10ad3227cd92b50