Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-id: <00092035-D10F-4034-B6E4-47A063FEB81E@mac.com>
Date: Wed, 10 Oct 2018 10:36:14 +1300
From: Michael Clark <michaeljclark@....com>
To: musl@...ts.openwall.com
Subject: Re: riscv port for review

Hi,

I have a status update. I haven’t made any changes to the musl port since last week but I did investigate and fix the stat issue in qemu-riscv32. I ran tests with riscv32 Linux kernel with glibc in QEMU full system emulation as Linux kernel is canonical for the ABI.

riscv32 is indeed a unique port in linux-kernel land. It does not define __ARCH_WANT_STAT64 in arch/riscv/include/asm/unistd.h (unlike all other 32-bit ports which confused me a bit). It does not have fstat64 and its stat structure matches rv64. I’m kind of stubborn so I had to see the test pass/fail so I spent some time getting riscv32 linux to build. I should submit a couple of small patches for riscv-linux.

I fixed riscv32 stat in riscv-qemu: https://github.com/riscv/riscv-qemu

RISC-V QEMU had the 32-bit asm-generic which has a 32-bit stat, but no fstat64. We may have missed a chunk when we rebased the 2016 riscv-qemu baseline. The stat patch is in qemu-for-upstream branch in the riscv-qemu branch.

We need to work on getting our QEMU changes upstream. We have problems with getting code into upstream QEMU as they have very strict code review policy on pull requests. Every commit must have “Reviewed-by:” with a “trusted reviewer”. It doesn’t seem to prevent changes coming from Linaro breaking the RISC-V port but it does prevent our fixes going in. My current focus is working on automated test cases for the fixes in the QEMU queue so we can change the discourse to does it pass an extensive set of tests. Currently the baseline for inclusion is does it compile and passes “make check”, have Reviewed-by and Signed-off-by tags and does it conform to the QEMU coding style (checkpatch.pl). The issue is we are making changes that typically require reading the Privileged ISA manual for verification and we don’t have high test case coverage for the Privileged ISA. The Base ISA has pretty good test coverage.

I would be happy if someone volunteered to help with the RISC-V musl port...

Michael

> On 10/10/2018, at 7:05 AM, Rich Felker <dalias@...c.org> wrote:
> 
> Ping.
> 
>> On Thu, Sep 27, 2018 at 10:46:33PM -0400, Rich Felker wrote:
>>> On Thu, Sep 27, 2018 at 10:24:04PM -0400, Rich Felker wrote:
>>> Pulled from here:
>>> https://github.com/riscv/riscv-musl/commit/6a4f4a9c774608add4b02f95322518bd2f5f51ee
>>> 
>>> Attached for review.
>> 
>> Review inline below:
>> 
>>> diff --git a/arch/riscv32/atomic_arch.h b/arch/riscv32/atomic_arch.h
>>> new file mode 100644
>>> index 0000000..93c89cc
>>> --- /dev/null
>>> +++ b/arch/riscv32/atomic_arch.h
>>> @@ -0,0 +1,35 @@
>>> +#define a_barrier a_barrier
>>> +static inline void a_barrier()
>>> +{
>>> +    __asm__ __volatile__ ("fence rw,rw" : : : "memory");
>>> +}
>>> +
>>> +#define a_ll a_ll
>>> +static inline int a_ll(volatile int *p)
>>> +{
>>> +    int v;
>>> +    __asm__ __volatile__ ("lr.w %0, (%1)" : "=&r"(v) : "r"(p));
>>> +    return v;
>>> +}
>>> +
>>> +#define a_sc a_sc
>>> +static inline int a_sc(volatile int *p, int v)
>>> +{
>>> +    int r;
>>> +    __asm__ __volatile__ ("sc.w %0, %2, (%1)" : "=&r"(r) : "r"(p), "r"(v) : "memory");
>>> +    return !r;
>>> +}
>>> +
>>> +#define a_cas a_cas
>>> +static inline int a_cas(volatile int *p, int t, int s)
>>> +{
>>> +    int old, tmp;
>>> +    __asm__("1:  lr.w    %0, %2      \n"
>>> +        "    bne     %0, %3, 1f  \n"
>>> +        "    sc.w    %1, %4, %2  \n"
>>> +        "    bnez    %1, 1b      \n"
>>> +        "1:                      \n"
>>> +        : "=&r"(old), "+r"(tmp), "+A"(*p)
>>> +        : "r"(t), "r"(s));
>>> +    return old;
>>> +}
>> 
>> Why are both a_ll/a_sc and a_cas defined, and why is a_cas missing
>> barriers? Normally if a_ll/a_sc/a_barrier are defined, the top-level
>> atomic.h should be allowed to generate a_cas in terms of them.
>> 
>>> diff --git a/arch/riscv32/bits/signal.h b/arch/riscv32/bits/signal.h
>>> new file mode 100644
>>> index 0000000..8b992cc
>>> --- /dev/null
>>> +++ b/arch/riscv32/bits/signal.h
>>> @@ -0,0 +1,113 @@
>>> +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
>>> + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
>>> +
>>> +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
>>> +# define MINSIGSTKSZ 2048
>>> +# define SIGSTKSZ 8192
>>> +#endif
>>> +
>>> +/* gregs[0] holds the program counter. */
>>> +
>>> +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
>>> +typedef unsigned long greg_t;
>>> +typedef unsigned long gregset_t[32];
>>> +
>>> +struct __riscv_f_ext_state {
>>> +    unsigned int f[32];
>>> +    unsigned int fcsr;
>>> +};
>>> +
>>> +struct __riscv_d_ext_state {
>>> +    unsigned long long f[32];
>>> +    unsigned int fcsr;
>>> +};
>>> +
>>> +struct __riscv_q_ext_state {
>>> +    unsigned long long f[64] __attribute__((aligned(16)));
>>> +    unsigned int fcsr;
>>> +    unsigned int reserved[3];
>>> +};
>>> +
>>> +union __riscv_fp_state {
>>> +    struct __riscv_f_ext_state f;
>>> +    struct __riscv_d_ext_state d;
>>> +    struct __riscv_q_ext_state q;
>>> +};
>>> +
>>> +typedef union __riscv_fp_state fpregset_t;
>>> +
>>> +typedef struct sigcontext {
>>> +    gregset_t gregs;
>>> +    fpregset_t fpregs;
>>> +} mcontext_t;
>>> +
>>> +#else
>>> +typedef struct {
>>> +    unsigned long gregs[32];
>>> +    unsigned long long fpregs[66];
>>> +} mcontext_t;
>>> +#endif
>> 
>> In the namespace-safe version of mcontext_t, the names gregs and
>> fpregs are not valid here. They would need to be __-prefixed or in
>> some other reserved namespace.
>> 
>>> +struct sigaltstack {
>>> +    void *ss_sp;
>>> +    int ss_flags;
>>> +    size_t ss_size;
>>> +};
>>> +
>>> +typedef struct __ucontext
>>> +{
>>> +    unsigned long uc_flags;
>>> +    struct __ucontext *uc_link;
>>> +    stack_t uc_stack;
>>> +    sigset_t uc_sigmask;
>>> +    char __unused[1024 / 8 - sizeof(sigset_t)];
>> 
>> This is an invalid array of size zero and should just be removed.
>> 
>>> +    mcontext_t uc_mcontext;
>>> +} ucontext_t;
>> 
>> ....
>> 
>>> diff --git a/arch/riscv32/crt_arch.h b/arch/riscv32/crt_arch.h
>>> new file mode 100644
>>> index 0000000..65187e1
>>> --- /dev/null
>>> +++ b/arch/riscv32/crt_arch.h
>>> @@ -0,0 +1,18 @@
>>> +__asm__(
>>> +".text\n"
>>> +".global " START "\n"
>>> +".type " START ",%function\n"
>>> +START ":\n"
>>> +".weak __global_pointer$\n"
>>> +".hidden __global_pointer$\n\t"
>>> +".option push\n"
>>> +".option norelax\n\t"
>>> +"lla gp, __global_pointer$\n"
>>> +".option pop\n\t"
>>> +"mv a0, sp\n"
>>> +".weak _DYNAMIC\n"
>>> +".hidden _DYNAMIC\n\t"
>>> +"lla a1, _DYNAMIC\n\t"
>>> +"andi sp, sp, -16\n\t"
>>> +"jal " START "_c"
>>> +);
>>> diff --git a/arch/riscv32/pthread_arch.h b/arch/riscv32/pthread_arch.h
>>> new file mode 100644
>>> index 0000000..feffaa4
>>> --- /dev/null
>>> +++ b/arch/riscv32/pthread_arch.h
>>> @@ -0,0 +1,12 @@
>>> +static inline struct pthread *__pthread_self()
>>> +{
>>> +    char *tp;
>>> +    __asm__ __volatile__("mv %0, tp" : "=r"(tp));
>>> +    return (void *)(tp - sizeof(struct pthread));
>>> +}
>>> +
>>> +#define TLS_ABOVE_TP
>>> +#define GAP_ABOVE_TP 0
>>> +#define TP_ADJ(p) ((char *)p + sizeof(struct pthread))
>>> +
>>> +#define MC_PC gregs[0]
>>> diff --git a/arch/riscv32/reloc.h b/arch/riscv32/reloc.h
>>> new file mode 100644
>>> index 0000000..d057bbe
>>> --- /dev/null
>>> +++ b/arch/riscv32/reloc.h
>>> @@ -0,0 +1,27 @@
>>> +#if defined __riscv_float_abi_soft
>>> +#define RISCV_FP_SUFFIX "-sf"
>>> +#elif defined __riscv_float_abi_single
>>> +#define RISCV_FP_SUFFIX "-sp"
>>> +#elif defined __riscv_float_abi_double
>>> +#define RISCV_FP_SUFFIX ""
>>> +#endif
>>> +
>>> +#define RISCV_LDSO_HELPER(x) "riscv" #x
>>> +#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x)
>>> +
>>> +#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) RISCV_FP_SUFFIX
>> 
>> Elsewhere it looks like little/big endian are both options, but I see
>> no endian variant here. If so this needs to be fixed.
>> 
>> Also what is __riscv_xlen? A predefined macro that expands to 32 or
>> 64? Since this file is just for 32-bit it should just be hard-coded
>> rather than assuming a macro would expand to the token 32 and not
>> (31+1) or some other expression equal to 32, I think.
>> 
>>> diff --git a/arch/riscv32/syscall_arch.h b/arch/riscv32/syscall_arch.h
>>> new file mode 100644
>>> index 0000000..bc60d1f
>>> --- /dev/null
>>> +++ b/arch/riscv32/syscall_arch.h
>>> @@ -0,0 +1,78 @@
>>> +#define __SYSCALL_LL_E(x) \
>>> +((union { long long ll; long l[2]; }){ .ll = x }).l[0], \
>>> +((union { long long ll; long l[2]; }){ .ll = x }).l[1]
>>> +#define __SYSCALL_LL_O(x) 0, __SYSCALL_LL_E((x))
>>> +
>>> +#define __asm_syscall(...) \
>>> +    __asm__ __volatile__ ("scall\n\t" \
>>> +    : "+r"(a0) : __VA_ARGS__ : "memory"); \
>>> +    return a0; \
>>> +
>>> +static inline long __syscall0(long n)
>>> +{
>>> +    register long a7 __asm__("a7") = n;
>>> +    register long a0 __asm__("a0");
>>> +    __asm_syscall("r"(a7))
>>> +}
>>> +
>>> +static inline long __syscall1(long n, long a)
>>> +{
>>> +    register long a7 __asm__("a7") = n;
>>> +    register long a0 __asm__("a0") = a;
>>> +    __asm_syscall("r"(a7), "0"(a0))
>>> +}
>>> +
>>> +static inline long __syscall2(long n, long a, long b)
>>> +{
>>> +    register long a7 __asm__("a7") = n;
>>> +    register long a0 __asm__("a0") = a;
>>> +    register long a1 __asm__("a1") = b;
>>> +    __asm_syscall("r"(a7), "0"(a0), "r"(a1))
>>> +}
>>> +
>>> +static inline long __syscall3(long n, long a, long b, long c)
>>> +{
>>> +    register long a7 __asm__("a7") = n;
>>> +    register long a0 __asm__("a0") = a;
>>> +    register long a1 __asm__("a1") = b;
>>> +    register long a2 __asm__("a2") = c;
>>> +    __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2))
>>> +}
>>> +
>>> +static inline long __syscall4(long n, long a, long b, long c, long d)
>>> +{
>>> +    register long a7 __asm__("a7") = n;
>>> +    register long a0 __asm__("a0") = a;
>>> +    register long a1 __asm__("a1") = b;
>>> +    register long a2 __asm__("a2") = c;
>>> +    register long a3 __asm__("a3") = d;
>>> +    __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3))
>>> +}
>>> +
>>> +static inline long __syscall5(long n, long a, long b, long c, long d, long e)
>>> +{
>>> +    register long a7 __asm__("a7") = n;
>>> +    register long a0 __asm__("a0") = a;
>>> +    register long a1 __asm__("a1") = b;
>>> +    register long a2 __asm__("a2") = c;
>>> +    register long a3 __asm__("a3") = d;
>>> +    register long a4 __asm__("a4") = e;
>>> +    __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4))
>>> +}
>>> +
>>> +static inline long __syscall6(long n, long a, long b, long c, long d, long e, long f)
>>> +{
>>> +    register long a7 __asm__("a7") = n;
>>> +    register long a0 __asm__("a0") = a;
>>> +    register long a1 __asm__("a1") = b;
>>> +    register long a2 __asm__("a2") = c;
>>> +    register long a3 __asm__("a3") = d;
>>> +    register long a4 __asm__("a4") = e;
>>> +    register long a5 __asm__("a5") = f;
>>> +    __asm_syscall("r"(a7), "0"(a0), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5))
>>> +}
>>> +
>>> +#define VDSO_USEFUL
>>> +/* We don't have a clock_gettime function.
>>> +#define VDSO_CGT_SYM "__vdso_clock_gettime"
>>> +#define VDSO_CGT_VER "LINUX_2.6" */
>> 
>> In that case VDSO_USEFUL might as well also be omitted for now.
>> 
>>> diff --git a/arch/riscv64/atomic_arch.h b/arch/riscv64/atomic_arch.h
>>> new file mode 100644
>>> index 0000000..018c7fd
>>> --- /dev/null
>>> +++ b/arch/riscv64/atomic_arch.h
>>> @@ -0,0 +1,66 @@
>>> +#define a_barrier a_barrier
>>> +static inline void a_barrier()
>>> +{
>>> +    __asm__ __volatile__ ("fence rw,rw" : : : "memory");
>>> +}
>>> +
>>> +#define a_ll a_ll
>>> +static inline int a_ll(volatile int *p)
>>> +{
>>> +    int v;
>>> +    __asm__ __volatile__ ("lr.w %0, %1" : "=&r"(v), "+A"(*p));
>>> +    return v;
>>> +}
>>> +
>>> +#define a_sc a_sc
>>> +static inline int a_sc(volatile int *p, int v)
>>> +{
>>> +    int r;
>>> +    __asm__ __volatile__ ("sc.w %0, %2, %1" : "=&r"(r), "+A"(*p) : "r"(v) : "memory");
>>> +return !r;
>>> +}
>>> +
>>> +#define a_cas a_cas
>>> +static inline int a_cas(volatile int *p, int t, int s)
>>> +{
>>> +    int old, tmp;
>>> +    __asm__("1:  lr.w    %0, %2      \n"
>>> +        "    bne     %0, %3, 1f  \n"
>>> +        "    sc.w    %1, %4, %2  \n"
>>> +        "    bnez    %1, 1b      \n"
>>> +        "1:                      \n"
>>> +        : "=&r"(old), "+r"(tmp), "+A"(*p)
>>> +        : "r"(t), "r"(s));
>>> +    return old;
>>> +}
>>> +
>>> +#define a_ll_p a_ll_p
>>> +static inline void *a_ll_p(volatile void *p)
>>> +{
>>> +    void *v;
>>> +    __asm__ __volatile__ ("lr.d %0, %1" : "=&r"(v), "+A"(*(long *)p));
>>> +    return v;
>>> +}
>>> +
>>> +#define a_sc_p a_sc_p
>>> +static inline int a_sc_p(volatile int *p, void *v)
>>> +{
>>> +    int r;
>>> +    __asm__ __volatile__ ("sc.d %0, %2, %1" : "=&r"(r), "+A"(*(long *)p) : "r"(v) : "memory");
>>> +    return !r;
>>> +}
>>> +
>>> +#define a_cas_p a_cas_p
>>> +static inline void *a_cas_p(volatile void *p, void *t, void *s)
>>> +{
>>> +    void *old;
>>> +    int tmp;
>>> +    __asm__("1:  lr.d    %0, %2      \n"
>>> +        "    bne     %0, %3, 1f  \n"
>>> +        "    sc.d    %1, %4, %2  \n"
>>> +        "    bnez    %1, 1b      \n"
>>> +        "1:                      \n"
>>> +        : "=&r"(old), "+r"(tmp), "+A"(*(long *)p)
>>> +        : "r"(t), "r"(s));
>>> +    return old;
>>> +}
>> 
>> Same comments about cas vs ll/sc, and lack of barrier, as 32-bit version.
>> 
>>> diff --git a/arch/riscv64/bits/signal.h b/arch/riscv64/bits/signal.h
>>> new file mode 100644
>>> index 0000000..8b992cc
>>> --- /dev/null
>>> +++ b/arch/riscv64/bits/signal.h
>>> @@ -0,0 +1,113 @@
>>> +#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
>>> + || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
>>> +
>>> +#if defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
>>> +# define MINSIGSTKSZ 2048
>>> +# define SIGSTKSZ 8192
>>> +#endif
>>> +
>>> +/* gregs[0] holds the program counter. */
>>> +
>>> +#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
>>> +typedef unsigned long greg_t;
>>> +typedef unsigned long gregset_t[32];
>>> +
>>> +struct __riscv_f_ext_state {
>>> +    unsigned int f[32];
>>> +    unsigned int fcsr;
>>> +};
>>> +
>>> +struct __riscv_d_ext_state {
>>> +    unsigned long long f[32];
>>> +    unsigned int fcsr;
>>> +};
>>> +
>>> +struct __riscv_q_ext_state {
>>> +    unsigned long long f[64] __attribute__((aligned(16)));
>>> +    unsigned int fcsr;
>>> +    unsigned int reserved[3];
>>> +};
>>> +
>>> +union __riscv_fp_state {
>>> +    struct __riscv_f_ext_state f;
>>> +    struct __riscv_d_ext_state d;
>>> +    struct __riscv_q_ext_state q;
>>> +};
>>> +
>>> +typedef union __riscv_fp_state fpregset_t;
>>> +
>>> +typedef struct sigcontext {
>>> +    gregset_t gregs;
>>> +    fpregset_t fpregs;
>>> +} mcontext_t;
>>> +
>>> +#else
>>> +typedef struct {
>>> +    unsigned long gregs[32];
>>> +    unsigned long long fpregs[66];
>>> +} mcontext_t;
>>> +#endif
>>> +
>>> +struct sigaltstack {
>>> +    void *ss_sp;
>>> +    int ss_flags;
>>> +    size_t ss_size;
>>> +};
>>> +
>>> +typedef struct __ucontext
>>> +{
>>> +    unsigned long uc_flags;
>>> +    struct __ucontext *uc_link;
>>> +    stack_t uc_stack;
>>> +    sigset_t uc_sigmask;
>>> +    char __unused[1024 / 8 - sizeof(sigset_t)];
>>> +    mcontext_t uc_mcontext;
>>> +} ucontext_t;
>> 
>> Same issues here as 32-bit.
>> 
>>> diff --git a/arch/riscv64/reloc.h b/arch/riscv64/reloc.h
>>> new file mode 100644
>>> index 0000000..8bd90dd
>>> --- /dev/null
>>> +++ b/arch/riscv64/reloc.h
>>> @@ -0,0 +1,27 @@
>>> +#if defined __riscv_float_abi_soft
>>> +#define RISCV_FP_SUFFIX "-sf"
>>> +#elif defined __riscv_float_abi_single
>>> +#define RISCV_FP_SUFFIX "-sp"
>>> +#elif defined __riscv_float_abi_double
>>> +#define RISCV_FP_SUFFIX ""
>>> +#endif
>>> +
>>> +#define RISCV_LDSO_HELPER(x) "riscv" #x
>>> +#define RISCV_LDSO(x) RISCV_LDSO_HELPER(x)
>>> +
>>> +#define LDSO_ARCH RISCV_LDSO(__riscv_xlen) RISCV_FP_SUFFIX
>> 
>> Same here.
>> 
>>> diff --git a/configure b/configure
>>> index 997e665..4d3d8b4 100755
>>> --- a/configure
>>> +++ b/configure
>>> @@ -322,6 +322,8 @@ microblaze*) ARCH=microblaze ;;
>>> or1k*) ARCH=or1k ;;
>>> powerpc64*) ARCH=powerpc64 ;;
>>> powerpc*) ARCH=powerpc ;;
>>> +riscv64*) ARCH=riscv64 ;;
>>> +riscv*) ARCH=riscv32 ;;
>>> sh[1-9bel-]*|sh|superh*) ARCH=sh ;;
>>> s390x*) ARCH=s390x ;;
>>> unknown) fail "$0: unable to detect target arch; try $0 --target=..." ;;
>>> @@ -640,6 +642,11 @@ trycppif __LITTLE_ENDIAN__ "$t" && SUBARCH=${SUBARCH}le
>>> trycppif _SOFT_FLOAT "$t" && fail "$0: error: soft-float not supported on powerpc64"
>>> fi
>>> 
>>> +if test "$ARCH" = "riscv" || test "$ARCH" = "riscv64" ; then
>>> +trycppif "RISCVEB || _RISCVEB || __RISCVEB || __RISCVEB__" "$t" && SUBARCH=${SUBARCH}eb
>> 
>> Predefined macros that violate the namespace (RISCVEB) shouldn't be
>> defined or observed.
>> 
>>> +trycppif __riscv_soft_float "$t" && SUBARCH=${SUBARCH}-sf
>>> +fi
>>> +
>>> if test "$ARCH" = "sh" ; then
>>> tryflag CFLAGS_AUTO -Wa,--isa=any
>>> trycppif __BIG_ENDIAN__ "$t" && SUBARCH=${SUBARCH}eb
>>> diff --git a/crt/riscv32/crti.s b/crt/riscv32/crti.s
>>> new file mode 100644
>>> index 0000000..6916bfd
>>> --- /dev/null
>>> +++ b/crt/riscv32/crti.s
>>> @@ -0,0 +1,11 @@
>>> +.section .init
>>> +.global _init
>>> +.type _init,%function
>>> +_init:
>>> +        ret
>>> +
>>> +.section .fini
>>> +.global _fini
>>> +.type _fini,%function
>>> +_fini:
>>> +        ret
>>> diff --git a/crt/riscv32/crtn.s b/crt/riscv32/crtn.s
>>> new file mode 100644
>>> index 0000000..e69de29
>> 
>> It looks like these are not used, right?
>> 
>>> diff --git a/include/elf.h b/include/elf.h
>>> index c229735..ec2e8fd 100644
>>> --- a/include/elf.h
>>> +++ b/include/elf.h
>>> @@ -3164,6 +3164,62 @@ enum
>>> #define R_BPF_NONE        0
>>> #define R_BPF_MAP_FD        1
>>> 
>>> +#define R_RISCV_NONE            0
>>> +#define R_RISCV_32              1
>>> +#define R_RISCV_64              2
>>> +#define R_RISCV_RELATIVE        3
>>> +#define R_RISCV_COPY            4
>>> +#define R_RISCV_JUMP_SLOT       5
>>> +#define R_RISCV_TLS_DTPMOD32    6
>>> +#define R_RISCV_TLS_DTPMOD64    7
>>> +#define R_RISCV_TLS_DTPREL32    8
>>> +#define R_RISCV_TLS_DTPREL64    9
>>> +#define R_RISCV_TLS_TPREL32     10
>>> +#define R_RISCV_TLS_TPREL64     11
>>> +
>>> +#define R_RISCV_BRANCH          16
>>> +#define R_RISCV_JAL             17
>>> +#define R_RISCV_CALL            18
>>> +#define R_RISCV_CALL_PLT        19
>>> +#define R_RISCV_GOT_HI20        20
>>> +#define R_RISCV_TLS_GOT_HI20    21
>>> +#define R_RISCV_TLS_GD_HI20     22
>>> +#define R_RISCV_PCREL_HI20      23
>>> +#define R_RISCV_PCREL_LO12_I    24
>>> +#define R_RISCV_PCREL_LO12_S    25
>>> +#define R_RISCV_HI20            26
>>> +#define R_RISCV_LO12_I          27
>>> +#define R_RISCV_LO12_S          28
>>> +#define R_RISCV_TPREL_HI20      29
>>> +#define R_RISCV_TPREL_LO12_I    30
>>> +#define R_RISCV_TPREL_LO12_S    31
>>> +#define R_RISCV_TPREL_ADD       32
>>> +#define R_RISCV_ADD8            33
>>> +#define R_RISCV_ADD16           34
>>> +#define R_RISCV_ADD32           35
>>> +#define R_RISCV_ADD64           36
>>> +#define R_RISCV_SUB8            37
>>> +#define R_RISCV_SUB16           38
>>> +#define R_RISCV_SUB32           39
>>> +#define R_RISCV_SUB64           40
>>> +#define R_RISCV_GNU_VTINHERIT   41
>>> +#define R_RISCV_GNU_VTENTRY     42
>>> +#define R_RISCV_ALIGN           43
>>> +#define R_RISCV_RVC_BRANCH      44
>>> +#define R_RISCV_RVC_JUMP        45
>>> +#define R_RISCV_RVC_LUI         46
>>> +#define R_RISCV_GPREL_I         47
>>> +#define R_RISCV_GPREL_S         48
>>> +#define R_RISCV_TPREL_I         49
>>> +#define R_RISCV_TPREL_S         50
>>> +#define R_RISCV_RELAX           51
>>> +#define R_RISCV_SUB6            52
>>> +#define R_RISCV_SET6            53
>>> +#define R_RISCV_SET8            54
>>> +#define R_RISCV_SET16           55
>>> +#define R_RISCV_SET32           56
>>> +#define R_RISCV_32_PCREL        57
>>> +
>>> #ifdef __cplusplus
>>> }
>>> #endif
>> 
>> This should be its own patch independent of the port; I can commit it
>> earlier.
>> 
>>> diff --git a/src/thread/riscv32/syscall_cp.s b/src/thread/riscv32/syscall_cp.s
>>> new file mode 100644
>>> index 0000000..71bf6d3
>>> --- /dev/null
>>> +++ b/src/thread/riscv32/syscall_cp.s
>>> @@ -0,0 +1,29 @@
>>> +.global __cp_begin
>>> +.hidden __cp_begin
>>> +.global __cp_end
>>> +.hidden __cp_end
>>> +.global __cp_cancel
>>> +.hidden __cp_cancel
>>> +.hidden __cancel
>>> +.global __syscall_cp_asm
>>> +.hidden __syscall_cp_asm
>>> +.type __syscall_cp_asm, %function
>>> +__syscall_cp_asm:
>>> +__cp_begin:
>>> +        lw t0, 0(a0)
>>> +        bnez t0, __cp_cancel
>>> +
>>> +        mv t0, a1
>>> +        mv a0, a2
>>> +        mv a1, a3
>>> +        mv a2, a4
>>> +        mv a3, a5
>>> +        mv a4, a6
>>> +        mv a5, a7
>>> +        lw a6, 0(sp)
>>> +        mv a7, t0
>>> +        scall
>>> +__cp_cancel:
>>> +        ret
>>> +__cp_end:
>>> +        j __cancel
>> 
>> The labels here are backwards. __cp_end must point immediately after
>> the syscall instruction, and __cp_end needs to jump to __cancel.
>> 
>>> diff --git a/src/thread/riscv64/syscall_cp.s b/src/thread/riscv64/syscall_cp.s
>>> new file mode 100644
>>> index 0000000..c745b32
>>> --- /dev/null
>>> +++ b/src/thread/riscv64/syscall_cp.s
>>> @@ -0,0 +1,29 @@
>>> +.global __cp_begin
>>> +.hidden __cp_begin
>>> +.global __cp_end
>>> +.hidden __cp_end
>>> +.global __cp_cancel
>>> +.hidden __cp_cancel
>>> +.hidden __cancel
>>> +.global __syscall_cp_asm
>>> +.hidden __syscall_cp_asm
>>> +.type __syscall_cp_asm, %function
>>> +__syscall_cp_asm:
>>> +__cp_begin:
>>> +        ld t0, 0(a0)
>>> +        bnez t0, __cp_cancel
>>> +
>>> +        mv t0, a1
>>> +        mv a0, a2
>>> +        mv a1, a3
>>> +        mv a2, a4
>>> +        mv a3, a5
>>> +        mv a4, a6
>>> +        mv a5, a7
>>> +        ld a6, 0(sp)
>>> +        mv a7, t0
>>> +        scall
>>> +__cp_cancel:
>>> +        ret
>>> +__cp_end:
>>> +        j __cancel
>>> -- 
>>> 2.10.0
>>> 
>> 
>> Likewise here.
>> 
>> Rich

Content of type "text/html" skipped

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.