Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20181009180515.GI17110@brightrain.aerifal.cx>
Date: Tue, 9 Oct 2018 14:05:15 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Re: riscv port for review

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

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.