Subject: Re: Failure to build librseq on ppc

From: Michael Ellerman <[email-masked]>
Date: Wed, 08 Jul 2020 22:27:27 +1000

Segher Boessenkool <[email-masked]> writes:
> Hi!
>
> On Tue, Jul 07, 2020 at 03:17:10PM -0400, Mathieu Desnoyers wrote:
>> I'm trying to build librseq at:
>> 
>> https://git.kernel.org/pub/scm/libs/librseq/librseq.git
>> 
>> on powerpc, and I get these errors when building the rseq basic
>> test mirrored from the kernel selftests code:
>> 
>> /tmp/ccieEWxU.s: Assembler messages:
>> /tmp/ccieEWxU.s:118: Error: syntax error; found `,', expected `('
>> /tmp/ccieEWxU.s:118: Error: junk at end of line: `,8'
>> /tmp/ccieEWxU.s:121: Error: syntax error; found `,', expected `('
>> /tmp/ccieEWxU.s:121: Error: junk at end of line: `,8'
>> /tmp/ccieEWxU.s:626: Error: syntax error; found `,', expected `('
>> /tmp/ccieEWxU.s:626: Error: junk at end of line: `,8'
>> /tmp/ccieEWxU.s:629: Error: syntax error; found `,', expected `('
>> /tmp/ccieEWxU.s:629: Error: junk at end of line: `,8'
>> /tmp/ccieEWxU.s:735: Error: syntax error; found `,', expected `('
>> /tmp/ccieEWxU.s:735: Error: junk at end of line: `,8'
>> /tmp/ccieEWxU.s:738: Error: syntax error; found `,', expected `('
>> /tmp/ccieEWxU.s:738: Error: junk at end of line: `,8'
>> /tmp/ccieEWxU.s:741: Error: syntax error; found `,', expected `('
>> /tmp/ccieEWxU.s:741: Error: junk at end of line: `,8'
>> Makefile:581: recipe for target 'basic_percpu_ops_test.o' failed
>
> You'll have to show the actual failing machine code, and with enough
> context that we can relate this to the source code.
>
> -save-temps helps, or use -S instead of -c, etc.

Attached below.

$ gcc -Wall basic_percpu_ops_test.s 
basic_percpu_ops_test.s: Assembler messages:
basic_percpu_ops_test.s:133: Error: operand out of domain (3 is not a multiple of 4)
basic_percpu_ops_test.s:133: Error: syntax error; found `,', expected `('
basic_percpu_ops_test.s:133: Error: junk at end of line: `,8'
basic_percpu_ops_test.s:136: Error: operand out of domain (3 is not a multiple of 4)
basic_percpu_ops_test.s:136: Error: syntax error; found `,', expected `('
basic_percpu_ops_test.s:136: Error: junk at end of line: `,8'
basic_percpu_ops_test.s:818: Error: operand out of domain (3 is not a multiple of 4)
basic_percpu_ops_test.s:818: Error: syntax error; found `,', expected `('
basic_percpu_ops_test.s:818: Error: junk at end of line: `,8'
basic_percpu_ops_test.s:821: Error: operand out of domain (3 is not a multiple of 4)
basic_percpu_ops_test.s:821: Error: syntax error; found `,', expected `('
basic_percpu_ops_test.s:821: Error: junk at end of line: `,8'
basic_percpu_ops_test.s:955: Error: operand out of domain (3 is not a multiple of 4)
basic_percpu_ops_test.s:955: Error: syntax error; found `,', expected `('
basic_percpu_ops_test.s:955: Error: junk at end of line: `,8'
basic_percpu_ops_test.s:958: Error: operand out of domain (3 is not a multiple of 4)
basic_percpu_ops_test.s:958: Error: syntax error; found `,', expected `('
basic_percpu_ops_test.s:958: Error: junk at end of line: `,8'
basic_percpu_ops_test.s:961: Error: operand out of domain (3 is not a multiple of 4)
basic_percpu_ops_test.s:961: Error: syntax error; found `,', expected `('
basic_percpu_ops_test.s:961: Error: junk at end of line: `,8'

$ sed '133!d' basic_percpu_ops_test.s
        ld %r17, 3,8
$ sed '136!d' basic_percpu_ops_test.s
        std 7, 3,8
$ sed '818!d' basic_percpu_ops_test.s
        ld %r17, 3,8
$ sed '821!d' basic_percpu_ops_test.s
        std 4, 3,8
$ sed '955!d' basic_percpu_ops_test.s
        ld %r17, 3,8
$ sed '958!d' basic_percpu_ops_test.s
        ld %r17, 3,8
$ sed '961!d' basic_percpu_ops_test.s
        std %r17, 3,8

 # 211 "../include/rseq/rseq-ppc.h" 1
        .pushsection __rseq_cs, "aw"
        .balign 32
        3:
        .long 0x0, 0x0
        .quad 1f, (2f - 1f), 4f
        .popsection
        .pushsection __rseq_cs_ptr_array, "aw"
        .quad 3b
        .popsection
        .pushsection __rseq_exit_point_array, "aw"
        .quad 1f, .L8
        .popsection
        lis %r17, (3b)@highest
        ori %r17, %r17, (3b)@higher
        rldicr %r17, %r17, 32, 31
        oris %r17, %r17, (3b)@high
        ori %r17, %r17, (3b)@l
        std %r17, 8(9)
        1:
        lwz %r17, 4(9)
        cmpw cr7, 10, %r17
        bne- cr7, 4f
        ld %r17, 3,8			<--- line 133
        cmpd cr7, %r17, 6
        bne- cr7, .L8
        std 7, 3,8
        2:
        .pushsection __rseq_failure, "ax"
        .long 0x0fe5000b
        4:
        b .L8
        .popsection

Tracking back to the source is "interesting", given there's a lot of
macros involved :)

I think that's from:

#define LOAD_WORD       "ld "

#define RSEQ_ASM_OP_CMPEQ(var, expect, label)                                   \
                LOAD_WORD "%%r17, %[" __rseq_str(var) "]\n\t"                   \
                CMP_WORD "cr7, %%r17, %[" __rseq_str(expect) "]\n\t"            \
                "bne- cr7, " __rseq_str(label) "\n\t"

static inline __attribute__((always_inline))
int rseq_cmpeqv_storev(intptr_t *v, intptr_t expect, intptr_t newv, int cpu)
{
        RSEQ_INJECT_C(9)

        __asm__ __volatile__ goto (
                RSEQ_ASM_DEFINE_TABLE(3, 1f, 2f, 4f) /* start, commit, abort */
                RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[cmpfail])
#ifdef RSEQ_COMPARE_TWICE
                RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error1])
                RSEQ_ASM_DEFINE_EXIT_POINT(1f, %l[error2])
#endif
                /* Start rseq by storing table entry pointer into rseq_cs. */
                RSEQ_ASM_STORE_RSEQ_CS(1, 3b, rseq_cs)
                /* cmp cpuid */
                RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, 4f)
                RSEQ_INJECT_ASM(3)
                /* cmp @v equal to @expect */
                RSEQ_ASM_OP_CMPEQ(v, expect, %l[cmpfail])			<----
                RSEQ_INJECT_ASM(4)
#ifdef RSEQ_COMPARE_TWICE
                /* cmp cpuid */
                RSEQ_ASM_CMP_CPU_ID(cpu_id, current_cpu_id, %l[error1])
                /* cmp @v equal to @expect */
                RSEQ_ASM_OP_CMPEQ(v, expect, %l[error2])
#endif
                /* final store */
                RSEQ_ASM_OP_FINAL_STORE(newv, v, 2)
                RSEQ_INJECT_ASM(5)
                RSEQ_ASM_DEFINE_ABORT(4, abort)
                : /* gcc asm goto does not allow outputs */
                : [cpu_id]              "r" (cpu),
                  [current_cpu_id]      "m" (__rseq_abi.cpu_id),
                  [rseq_cs]             "m" (__rseq_abi.rseq_cs),
                  [v]                   "m" (*v),				<----
                  [expect]              "r" (expect),
                  [newv]                "r" (newv)
                  RSEQ_INJECT_INPUT
                : "memory", "cc", "r17"
                  RSEQ_INJECT_CLOBBER
                : abort, cmpfail
#ifdef RSEQ_COMPARE_TWICE
                  , error1, error2
#endif
        );

cheers