On Wed, 13 Apr 2011, Frederic Turgis wrote:

> Hi,
> 
> In the context of systemtap testsuite, I had some compilation issues
> "invalid lvalue output in asm 1". I have root-caused that to code in
> the tool that is a (old) duplicate of arch/arm/include/asm/uaccess.h
> macro __put_user_asm_dword(x, __pu_addr, err) => 64bits storage.
> __pu_addr is storage address
> 
> The xxx_byte/half/word versions are OK. The main difference is that
> __pu_addr is only read while read and write in dword version (inline
> assembly "+r" modifier)
> 
> #define __stp_put_user_asm_dword(x,__pu_addr,err)               \
>         __asm__ __volatile__(                                   \
>         "1:     str     " __reg_oper1 ", [%1], #4\n"            \ ->
> __pu_addr is read but also written for next operation
>         "2:     str     " __reg_oper0 ", [%1], #0\n"            \
> ...
>         : "+r" (err), "+r" (__pu_addr)                          \ ->
> "r" (__pu_addr) for other versions
>         : "r" (x), "i" (-EFAULT)                                \
>         : "cc")
> 
> As my knowledge of inline assembly is poor, I am checking if this
> reminds anything to anyone (compilation option, out of date syntax,
> ...) before investigating deeper.

No, the assembly is fine.  The problem is most likely in your usage of 
those macros.  If you do something like:

int blah(int foo, long long *ptr1, long long *ptr2)
{
        int err = 0;
        __stp_put_user_asm_dword(0, foo ? ptr1 : ptr2, err);
        return err;
}

then you'll get the above error.  If instead you do:

int blah(int foo, long long *ptr1, long long *ptr2)
{
        int err = 0;
        long long ptr = foo ? ptr1 : ptr2;
        __stp_put_user_asm_dword(0, ptr, err);
        return err;
}

then it'll be fine.

In the kernel version you'll find that the equivalent macro is always 
used only within __put_user_err() that does:

#define __put_user_err(x,ptr,err)                                       \
do {                                                                    \
        unsigned long __pu_addr = (unsigned long)(ptr);                 \
        [...]

so here whatever expression provided as an address is always evaluated 
and put into a variable before it is passed to __put_user_asm_dword().


Nicolas






> 
> I have put most recent code version from kernel in the tool but still
> it fails. However, looking again at kernel code while writing this
> mail, macro may be used only if CONFIG_MMU is not defined. I will
> cross-check tomorrow.
> 
> Regards
> Fred
> 
> _______________________________________________
> linaro-dev mailing list
> linaro-dev@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/linaro-dev
> 

_______________________________________________
linaro-dev mailing list
linaro-dev@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-dev

Reply via email to